【问题标题】:Multiple @Transactional annotation over more than 2 methods not working超过 2 个方法的多个 @Transactional 注释不起作用
【发布时间】:2014-10-11 07:27:24
【问题描述】:

我有两种交易方法,如下所示

Class MyTransaction(){

@Transactional
public void initialTranx(){

  String userId = 500;
  // do some user specific activity
 updateUserBalance(500);
  // check user balance
}

@Transactional
private void updateUserBalance(int userId){
 // codes for updating balance to 400
}

}

现在正在调用 initialTranx() 方法,该方法在内部调用私有方法 updateUserBalance(userid),但是在我的 updateUserBalance 方法执行后余额没有得到更新。只有在完成公共方法(父方法)事务后才会提交。

在完成私有方法本身之后,我需要提交我的第二个方法的事务。

我正在为 DB 和 Spring Data JPA 使用 mysql。

请有人指导我。

【问题讨论】:

    标签: spring jpa transactions


    【解决方案1】:
    1. @Transactional 不适用于私有方法,请使用公共方法。根据类代理策略,调用同一个类中的方法也可能不会触发事务。

    2. JPA 不正式支持嵌套事务。可能是work with Spring to some extent,但可能会发生奇怪的错误。

    3. 如果您想在事务提交之前强制更改数据库,可以使用EntityManager.flush()

    【讨论】:

    • 这是一个很好的答案。改进它的一个建议:另一种选择是使用programmatic transaction management。这将解决#1,但需要一些额外的重构来解决#2。
    【解决方案2】:

    使用 em.flush() 不是一个好习惯。我建议您使用传播功能。见link

    public class ServiceClass {
    
        @Transactional(propagation = Propagation.REQUIRES_NEW)
        public void updateUserBalance(int userId){
            // codes for updating balance to 400
        }
    
    }
    

    【讨论】:

    • 我在公共方法中尝试了@Transactional(propagation = Propagation.REQUIRES_NEW),但它不起作用..感谢您的建议
    【解决方案3】:

    此方法不适用于同一类中的两个方法,因为当 initialTranx 调用 updateUserBalance 时,它​​会在目标对象而不是代理对象上调用此方法。如果您将 updateUserBalance 移动到一个单独的类,那么它将与 @Transactional(propagation = Propagation.REQUIRES_NEW)

    【讨论】:

      猜你喜欢
      • 2018-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-07
      • 2019-12-07
      相关资源
      最近更新 更多