java多线程Spring事务
假设我们进入一个方法并在主线程中启动一个事务。在这个方法中,有一些异步方法,所以我们在这个方法中又创建了两个线程
Thread 1 --> SubMethod1 --> Saving (t=1)
^
|
MainThread --> MainMethod --> Saving (t=3)
|
v
Thread 2 --> SubMethod2 --> Exception while saving (t=2).
由于线程2得到了一个异常,我想回滚其他线程完成的所有事务。然而,尽管主线程2拥有的事务可以回滚,但我不能回滚线程1的工作。 我使用的是Spring/Hibernate,所以你有什么办法来管理它以及如何应用它吗
谢谢
# 1 楼答案
从Professional Java for Web Applications by Nicholas S. Williams
Spring中的事务范围仅限于事务开始所在的线程。然后,事务管理器将事务链接到事务生命周期内同一线程中使用的托管资源。在使用Java持久性API时,您使用的资源是
EntityManager
。它的功能相当于Hibernate ORM的会话和JDBC的连接。通常,在开始事务和执行JPA操作之前,您会从EntityManagerFactory
获取EntityManager
。然而,这不适用于代表您管理事务的Spring框架模型。这个问题的解决方案是org.springframework.orm.jpa.support.SharedEntityManagerBean
。在Spring框架中配置JPA时,它会创建一个SharedEntityManagerBean
来代理EntityManager
接口。然后,这个代理被注入到您的JPA存储库中。在这个代理实例上调用EntityManager
方法时,后台会发生以下情况:➤➤ 如果当前线程已经有一个带有活动事务的实
EntityManager
,它会将调用委托给该EntityManager
上的方法➤➤ 否则,Spring框架从
EntityManagerFactory
获取一个新的EntityManager
,启动一个事务,并将两者绑定到当前线程。然后,它将调用委托给该EntityManager
上的方法。当事务被提交或回滚时,Spring将事务和EntityManager
从线程中解除绑定,然后关闭EntityManager
。同一线程上的未来@Transactional
操作(即使在同一个请求中)再次启动流程,从工厂获得一个新的EntityManager
并开始一个新事务。这样,就不会有两个线程同时使用EntityManager
,给定线程在任何给定时间只有一个事务和一个活动的EntityManager
如果你不是使用Spring MVC,那么你应该在Hibernate中使用
SessionFactory
进行会话。Hibernate会话代表事务从开始到结束的生命周期。根据应用程序的架构,这可能不到一秒钟或几分钟;在一个web应用程序中,它可以是一个请求中的几个事务之一,一个持续整个请求的事务,或者一个跨越多个请求的事务。不是线程安全的Session
一次只能在一个线程中使用,它负责管理实体的状态# 2 楼答案
这篇文章似乎很好地涵盖了这个问题,并提到了一个正在做类似事情的项目