当前位置: 首页 > 知识库问答 >
问题:

多线程Spring Transaction

董翰池
2023-03-14

假设我们进入一个方法并在主线程中启动一个事务。在这个方法中,有一些异步方法,所以我们在这个方法中创建了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,所以你有什么想法来管理这个以及如何应用?

谢谢

共有2个答案

郭博涉
2023-03-14

这篇文章https://dzone . com/articles/spring-transaction-management-over-multiple-thread-1似乎很好地涵盖了这个问题,并提到了一个正在做类似事情的项目。

宓英哲
2023-03-14

摘自Nicholas S. Williams的《面向Web应用程序的专业Java》

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

➤➤ 如果当前线程已经有一个真正的<code>EntityManager

➤➤否则,Spring Framework从< code > entitymanager factory 获取一个新的< code>EntityManager,启动一个事务,并将两者绑定到当前线程。然后,它将调用委托给该< code>EntityManager上的方法。当事务被提交或回滚时,Spring从线程中解除事务和< code>EntityManager的绑定,然后关闭< code>EntityManager。同一线程上的未来< code>@Transactional操作(甚至在同一请求中)会重新开始该流程,从工厂获取新的< code>EntityManager并开始新的事务。这样,没有两个线程同时使用< code>EntityManager,并且给定的线程在任何给定的时间都只有一个事务和一个< code>EntityManager处于活动状态。

如果您不使用Spring MVC,那么您将在Hibernate中使用< code>SessionFactory获得会话。Hibernate会话从头到尾代表了一个事务的生命。根据应用程序的架构,这可能不到一秒或几分钟;在web应用程序中,它可以是一个请求中的几个事务之一,一个持续整个请求的事务,或者一个跨越多个请求的事务。< code>Session不是线程安全的,一次只能在一个线程中使用,它负责管理实体的状态。

 类似资料:
  • typora-copy-images-to: img 1. 多线程概述 人们在日常生活中,很多事情都是可以同时进行的。例如,一个人可以一边听音乐,一边打扫房间,可以一边吃饭,一边看电视。在使用计算机时,很多任务也是可以同时进行的。例如,可以一边浏览网页,一边打印文档,还可以一边聊天,一边复制文件等。计算机这种能够同时完成多项任务的技术,就是多线程技术。Java是支持多线程的语言之一,它内置了对多线

  • 使用 [Web Workers][web-workers]可以在系统级线程中运行JavaScript。 多线程Node.js 在 webPreferences中将 n​​odeIntegrationInWorker选项设置为 true,可以在Electron的Web Workers中使用Node.js功能: 1 let win = new BrowserWindow({ 2 webPreferen

  • If you use Casbin in a multi-threading manner, you can use the synchronized wrapper of the Casbin enforcer: https://github.com/casbin/casbin/blob/master/enforcer_synced.go (GoLang) and https://github.

  • 多线程 Swift多线程编程方案 Thread Cocoa Operation (Operation 和 OperationQueue) Grand Central Dispath (GCD) 1. Thread在三种多线程技术中是最轻量级的, 但需要自己管理线程的生命周期和线程同步. 线程同步对数据的加锁会有一定的系统开销. detachNewThread(_ block: @escaping

  • 在多线程运行环境中, Configuration 实例, Template 实例和数据模型应该是永远不能改变(只读)的对象。 也就是说,创建和初始化它们(如使用 set... 方法)之后,就不能再修改它们了(比如不能再次调用 set... 方法)。 这就允许我们在多线程环境中避免代价很大的同步锁问题。要小心 Template 实例; 当使用了 Configuration.getTemplate 方

  • 多任务可以由多进程完成,也可以由一个进程内的多线程完成。 我们前面提到了进程是由若干线程组成的,一个进程至少有一个线程。 由于线程是操作系统直接支持的执行单元,因此,高级语言通常都内置多线程的支持,Python也不例外,并且,Python的线程是真正的Posix Thread,而不是模拟出来的线程。 Python的标准库提供了两个模块:thread和threading,thread是低级模块,th

  • 多任务可以由多进程完成,也可以由一个进程内的多线程完成。 我们前面提到了进程是由若干线程组成的,一个进程至少有一个线程。 由于线程是操作系统直接支持的执行单元,因此,高级语言通常都内置多线程的支持,Python也不例外,并且,Python的线程是真正的Posix Thread,而不是模拟出来的线程。 Python的标准库提供了两个模块:_thread和threading,_thread是低级模块,

  • 通过Web Workers,可以实现用操作系统级别的线程来跑JavaScript 多线程的Node.js 可以在Electron的Web Workers里使用Node.js的特性。要用的话,需把webPreferences中的nodeIntegrationInWorker选项设置为true const win = new BrowserWindow({ webPreferences: {