本文介绍了多线程Spring事务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Assume that we go inside a method and start a transaction in main thread. In this method, there are some async methods so we created 2 more threads inside this method;

                 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,所以您有任何想法来管理它以及如何应用吗?

Since thread 2 gets an exception, I want to rollback all transactions done by other threads. However, although transactions owned by main thread an Thread 2 can be roll-backed, I cannot roll-back thread 1 work.I am using Spring/Hibernate, so do you have any idea to manage this and how to apply?

谢谢

推荐答案

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

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

The transaction scope in Spring is limited to the thread the transaction begins in. The transaction manager then links the transaction to managed resources used in the same thread during the life of the transaction. When using the Java Persistence API, the resource you work with is the EntityManager. It is the functional equivalent of Hibernate ORM’s Session and JDBC’s Connection. Normally, you would obtain an EntityManager from the EntityManagerFactory before beginning a transaction and performing JPA actions. However, this does not work with the Spring Framework model of managing transactions on your behalf. The solution to this problem is the org.springframework.orm.jpa.support.SharedEntityManagerBean. When you configure JPA in Spring Framework, it creates a SharedEntityManagerBean that proxies the EntityManager interface. This proxy is then injected into your JPA repositories. When an EntityManager method is invoked on this proxy instance, the following happens in the background:

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

➤➤ If the current thread already has a real EntityManager with an active transaction, it delegates the call to the method on that EntityManager.

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

➤➤ Otherwise, Spring Framework obtains a new EntityManager from the EntityManagerFactory, starts a transaction, and binds both to the current thread. It then delegates the call to the method on that EntityManager. When the transaction is either committed or rolled back, Spring unbinds the transaction and the EntityManager from the thread and then closes the EntityManager. Future @Transactional actions on the same thread (even within the same request) start the process over again, obtaining a new EntityManager from the factory and beginning a new transaction. This way, no two threads use an EntityManager at the same time, and a given thread has only one transaction and one EntityManager active at any given time.

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

If you were not to use Spring MVC then you would have gotten the session using SessionFactory in Hibernate. Hibernate Sessions represent the life of a transaction from start to finish. Depending on how your application is architected, that might be less than a second or several minutes; and in a web application, it could be one of several transactions in a request, a transaction lasting an entire request, or a transaction spanning multiple requests. A Session, which is not thread-safe and must be used only in one thread at a time, is responsible for managing the state of entities.

这篇关于多线程Spring事务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-03 21:54