Spring中的事务提交事件

如果想在spring操作事务结束后执行一些代码,应该怎么办?

为什么要这样?比如我们在事务中给其他系统发了消息,期望事务提交后过一会收到这个系统的回应,然后操作刚刚提交的数据。但是如果回应来的太快就像龙卷风,我们的事务是托管给Spring的可能还没提交,也就没法操作了

一个方案是使用 ApplicationEventPublisher,可以参考我之前的千万访问量博客
https://www.iteye.com/blog/somefuture-2405963

登陆访问量是100多万,我就假设总访问量是10倍吧哈哈

这个API是 Spring 1 就提供的,从 Spring 5 开始,提供了一个新的事物相关的API,叫 TransactionSynchronization 事物同步机制。

上代码

先编写一个Bean实TransactionSynchronization接口

java 复制代码
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()方法来注册事务同步回调

java 复制代码
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();
    }
}

基本上使用它还是为了操作数据,所以需要把参数传给他。

一 成员变量

最简单的就是加一个成员属性。

java 复制代码
@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();
    }
}

二 每次创建匿名类对象

java 复制代码
@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实例。

相关推荐
ModestCoder_1 分钟前
将一个新的机器人模型导入最新版isaacLab进行训练(以unitree H1_2为例)
android·java·机器人
a1800793108022 分钟前
软件工程面试题(二十二)
java·面试·软件工程
RainbowSea25 分钟前
4. RabbitMQ 发布确认的配置详细说明
java·消息队列·rabbitmq
robin_suli37 分钟前
Spring事务的传播机制
android·java·spring
青云交38 分钟前
Java 大视界 -- Java 大数据在智能电网电力市场交易数据分析与策略制定中的关键作用(162)
java·大数据·数据分析·交易策略·智能电网·java 大数据·电力市场交易
m0Java门徒44 分钟前
Java 递归全解析:从原理到优化的实战指南
java·开发语言
云徒川1 小时前
【设计模式】原型模式
java·设计模式·原型模式
张张张3121 小时前
4.2学习总结 Java:list系列集合
java·学习
KATA~1 小时前
解决MyBatis-Plus枚举映射错误:No enum constant问题
java·数据库·mybatis
xyliiiiiL2 小时前
一文总结常见项目排查
java·服务器·数据库