如果想在spring操作事务结束后执行一些代码,应该怎么办? 为什么要这样?比如我们在事务中给其他系统发了消息,期望事务提交后过一会收到这个系统的回应,然后操作刚刚提交的数据。但是如果回应来的太快就像龙卷风,我们的事务是托管给Spring的可能还没提交,也就没法操作了 一个方案是使用 Applica
在Spring中,如果需要在事务操作结束后执行一些代码,可以采取哪些方法呢?
为什么需要这样做呢?比如,在事务中向其他系统发送消息,希望在事务提交后一段时间内收到该系统的响应,然后对刚刚提交的数据进行操作。但是如果响应太快,就像龙卷风一样,我们的事务可能还没有提交,这样就无法进行操作。
一种解决方案是使用
ApplicationEventPublisher
,可以参考之前的博客:
https://www.iteye.com/blog/somefuture-2405963
博客访问量超过100万,我们假设总访问量是10倍哈哈
这个API是Spring 1就提供的。从Spring 5开始,提供了一个新的事务相关的API,叫
TransactionSynchronization
事务同步机制。
首先编写一个Bean实现
TransactionSynchronization
接口
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.stereotype.Component;
@Component
public class AfterTransactionCommitExecutor implements TransactionSynchronization {
@Override
public void afterCommit() {
// 事务提交后执行的操作
System.out.println("事务已提交,执行后续操作");
}
// 其他需要重写的方法...
public void registerSynchronization() {
// 注册当前实例到事务同步管理器
TransactionSynchronizationManager.registerSynchronization(this);
}
}
然后,在服务层或者合适的地方调用
registerSynchronization()
方法来注册事务同步回调
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class SomeService {
@Autowired
private AfterTransactionCommitExecutor afterTransactionCommitExecutor;
@Transactional
public void doWork() {
// 业务逻辑...
// 注册事务同步回调
afterTransactionCommitExecutor.registerSynchronization();
}
}
基本上使用它还是为了操作数据,所以需要把参数传给他。
最简单的方法是添加一个成员属性。
@Component
public class AfterTransactionCommitExecutor extends TransactionSynchronizationAdapter {
private Object parameter;
@Override
public void afterCommit() {
// 事务提交后使用参数执行操作
doSomethingWithParameter(parameter);
}
public void setParameter(Object parameter) {
this.parameter = parameter;
}
private void doSomethingWithParameter(Object parameter) {
}
public void registerSynchronization() {
TransactionSynchronizationManager.registerSynchronization(this);
}
}
@Service
public class SomeService {
@Autowired
private AfterTransactionCommitExecutor afterTransactionCommitExecutor;
@Transactional
public void doWork(Object parameter) {
// 设置参数
afterTransactionCommitExecutor.setParameter(parameter);
// 注册事务同步回调
afterTransactionCommitExecutor.registerSynchronization();
}
}
@Service
public class SomeService {
@Transactional
public void doWork(final Object parameter) {
// 业务逻辑...
// 注册事务同步回调并传递参数
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
@Override
public void afterCommit() {
doSomethingWithParameter(parameter);
}
});
}
private void doSomethingWithParameter(Object parameter) {
// 使用参数执行相关操作
}
}
需要注意的是,使用成员变量传递参数时,如果多个事务并发执行,可能会存在线程安全问题。为了避免这个问题,可以使用ThreadLocal来存储参数,或者在事务方法中每次都创建一个新的TransactionSynchronization实例。
小编推荐阅读