监听事务
一、背景
项目中有很多给客户端发送点对点消息的代码,这些代码很多都被service里被@Transactional修饰的方法调用。
问题就出在这,有的时候事务可能还没完成提交,点对点消息可能就发出去了,客户端收到消息开始请求接口,请求到了旧数据。
这种情况就需要考虑将数据库操作与点对点消息进一步解耦了。
二、TransactionSynchronizationManager
TransactionSynchronizationManager提供了事务各阶段操作的回调。
public interface TransactionSynchronization extends Flushable {
/** Completion status in case of proper commit. */
int STATUS_COMMITTED = 0;
/** Completion status in case of proper rollback. */
int STATUS_ROLLED_BACK = 1;
/** Completion status in case of heuristic mixed completion or system errors. */
int STATUS_UNKNOWN = 2;
default void suspend() {}
default void resume() {}
@Override
default void flush() {}
default void beforeCommit(boolean readOnly) {}
default void beforeCompletion() {}
default void afterCommit() {}
default void afterCompletion(int status) {}
}
使用:
@Transactional
public void updateXXX(XXX x){
// .......
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
public void afterCommit() {
System.out.println("事务提交后");
}
});
// .......
}
三、TransactionalEventListener
3.1 定义事件
利用到了spring的事件机制,需要先定义事件:
public class CustomTransactionEvent extends ApplicationEvent {
public CustomTransactionEvent(Object source) {
super(source);
}
}
3.2 定义listener
@Component
public class CustomTransactionListener {
@TransactionalEventListener(
//监听的事件
classes=CustomTransactionEvent.class,
//监听的事务阶段
phase = TransactionPhase.AFTER_COMMIT,
//无事务下是否执行此监听器
fallbackExecution = true
)
public void sendMess(CustomTransactionEvent event){
//...
}
}
3.3 发布事件
@Transactional
public void updateXXX(XXX X){
var event = new CustomTransactionEvent(x);
applicationEventPublisher.publishEvent(event);
// ...
}
Loading...