如何在多线程中使用spring事务

Posted

技术标签:

【中文标题】如何在多线程中使用spring事务【英文标题】:How to use spring transaction in multithread 【发布时间】:2012-05-11 13:07:23 【问题描述】:

我有一个方法如下:

ClassA.java
@Transactional
public void methodA()        
    ExecutorService executorService = Executors.newFixedThreadPool(4);
    executorService.execute(new Runnable() 
        public void run() 
            classB.methodB();
        
);

ClassB.java
@Transactional
public void methodB()
    updateDB();

methodB 能行得通吗?据我了解,methodB会附加methodA的事务,如果methodA在methodB之前退出怎么办?我猜只有methodA可以被事务提交。但是methodB不会提交,因为之前已经提交了事务。

我可以将@Transactional(propagation = Propagation.REQUIRES_NEW) 用于方法B。这可以让 methodB 有一个新的事务。但是根据spring doc,methodA的transcation会在调用methodB时暂停。我在这里感到很困惑。

谁能帮我解决这个问题?提前致谢。

【问题讨论】:

你到底想让它做什么? 【参考方案1】:

不,methodB() 不会在与methodA() 相同的事务中执行。 Spring 的 @Transactional 仅适用于单个线程 - 它在线程首次进入带有 @Transactional 的方法(或带有 @Transactional 的类中的方法)时创建一个会话,然后在离开该方法时提交它。

在您的示例中,事务将在您安排线程池中的作业后结束。 methodB() 会有自己的交易。

【讨论】:

您能否建议如何监控它们是否不是同一个事务?我发现事务没有提交。 @Jacky 两个事务中哪一个没有提交? 方法B的事务没有提交。 我真的不知道是什么问题,但一个疯狂的猜测是 ClassB 不是 Spring bean - 请参阅 static.springsource.org/spring/docs/3.1.x/… 它是一个 Spring bean。在我让它在同一个线程中执行后它运行良好,这意味着我删除了 executorService 的使用。

以上是关于如何在多线程中使用spring事务的主要内容,如果未能解决你的问题,请参考以下文章

Spring在多线程环境下如何确保事务一致性

无法在多文档事务中创建命名空间(MongoDB 4.0、Spring Data 2.1.0、Spring Boot)

利用spring实现多线程 + 事务回滚

spring如何保证并发的同时保证事务

如何在Spring事务提交后进行异步操作

spring事务管理属性为只读是啥意思