如何配置要使用的事务管理器而不必覆盖所有@Transactional方法

时间:2013-02-07 17:42:05

标签: java spring transactions

长时间听众第一次来电。

我们有一个包含公共事务逻辑的AbstractService.java类。并非此类中的所有方法都是事务性的。曾经的那些是用spring的@Transactional注释注释的。

现在,AbstractService的每个实现都可能具有不同的事务管理器。这可以通过覆盖抽象类中的方法在具体类中配置,并提供不同的tx管理器:

  

@Transactional(值= TRANSACTION_MANAGER)

由于“注释属性Transactional.value的值必须是常量表达式”,因此无法将事务管理器名称传递给抽象类。

据我所知,有两种配置事务管理器的方法:

  1. 覆盖具体类中的每个@Transactional方法只是为了调用super方法:

     @Transactional(timeout = 60, value = TRANSACTION_MANAGER)
     @Override
     public String editEntity(Integer id, Integer columnPosition, Object value) {
    return super.editEntity(id, columnPosition, value);
    
  2. 在类级别添加@Transactional注释。这会强制在事务中处理非事务性方法,并且由于非事务性方法调用其他事务性方法,我们最终会使用嵌套的tx汤。

  3. 有第三种选择吗?像现在已弃用的弹簧测试@NotTransactional这样的东西可以与上面的选项2一起完成。

    差不多三年前有人问过very similar question。既然Spring已经发生了很多事情,那么我们还有另一种选择吗?

    尽管如此,自定义注释答案并没有解决这个问题。

    我的问题可以概括为:

    如何配置事务而不必仅覆盖所有事务方法来指定事务管理器?

1 个答案:

答案 0 :(得分:2)

我建议您将AbstractService重构为三个类:

  • 第一个类是当前的AbstractService,它的接口,方法签名等,以保持与任何现有子类的二进制兼容,但所有实现都已被删除。
  • 第二个类包含所有事务性的业务逻辑,因此它使用@Transactional注释(在类级别使用正确的事务管理器)。
  • 第三类包含所有非事务性业务逻辑。

现在,您只需将最后两个类自动装入重构的AbstractService,它只是将传入的方法调用委托给移动到其中一个新创建的类中的实现。