多线程Spring事务

Jav*_*hip 4 java spring multithreading hibernate spring-transactions

假设我们进入一个方法并在主线程中启动事务。在此方法中,有一些异步方法,因此我们在该方法内又创建了2个线程;

                 Thread 1 --> SubMethod1 --> Saving (t=1)
                   ^
                   |
MainThread --> MainMethod --> Saving (t=3)
                   |
                   v   
                 Thread 2 --> SubMethod2 --> Exception while saving (t=2).
Run Code Online (Sandbox Code Playgroud)

由于线程2发生异常,因此我想回滚其他线程完成的所有事务。但是,尽管可以回滚线程2的主线程拥有的事务,但我无法回滚线程1的工作。我正在使用Spring / Hibernate,所以您有什么想法来进行管理以及如何应用?

谢谢

Far*_*raz 6

来自Nicholas S. Williams的Web应用程序专业Java

Spring中的事务范围仅限于事务开始的线程。然后,事务管理器将事务链接到事务有效期内在同一线程中使用的托管资源。使用Java Persistence API时,您使用的资源是EntityManager。它在功能上等同于Hibernate ORM的Session和JDBC的Connection。通常情况下,你会获得一个EntityManagerEntityManagerFactory开始交易,并执行JPA动作之前。但是,这不适用于代表您管理事务的Spring Framework模型。解决此问题的方法是org.springframework.orm.jpa.support.SharedEntityManagerBean。在Spring Framework中配置JPA时,它会创建一个SharedEntityManagerBean代理EntityManager接口。然后将此代理注入到您的JPA存储库中。当一个EntityManager 在此代理实例上调用方法,在后台发生以下情况:

?? 如果当前线程已经具有EntityManager带活动事务的实数,则它将调用委托给该方法上的方法EntityManager

?? 否则,Spring Framework EntityManager将从中获取新的内容EntityManagerFactory,启动事务,并将两者都绑定到当前线程。然后,将调用委托给上的方法EntityManager。当事务被提交或回滚时,Spring EntityManager从线程取消绑定事务和 ,然后关闭EntityManager@Transactional在同一线程上进行的后续操作(即使在同一请求中)也将重新开始该过程,EntityManager从工厂获取新的内容并开始新的事务。这样,不会有两个线程同时使用an EntityManager,并且给定线程只有一个事务,并且EntityManager在给定时间只有一个活动。

如果您使用Spring MVC,那么您将SessionFactory在Hibernate中使用该会话。休眠会话代表事务从头到尾的生命周期。取决于您的应用程序的架构方式,可能少于一秒钟或几分钟。在Web应用程序中,它可能是请求中的多个事务之一,持续整个请求的事务或跨多个请求的事务。A Session不是线程安全的,并且一次只能在一个线程中使用,它负责管理实体的状态。