编程语言
首页 > 编程语言> > java-多线程Spring事务

java-多线程Spring事务

作者:互联网

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

                 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,所以您有什么想法来进行管理以及如何应用?

谢谢

解决方法:

Professional Java for Web Applications by Nicholas S. Williams

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

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

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

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

标签:spring-transactions,multithreading,hibernate,spring,java
来源: https://codeday.me/bug/20191025/1925056.html