有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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,所以你有什么办法来管理它以及如何应用它吗

谢谢


共 (2) 个答案

  1. # 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. # 2 楼答案

    这篇文章似乎很好地涵盖了这个问题,并提到了一个正在做类似事情的项目