4

长时间的听众第一次来电。

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

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

@Transactional(值=TRANSACTION_MANAGER)

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

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

  1. 重写具体类中的每个 @Transactional 方法只是为了调用超级方法:

     @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 汤。

有第三种选择吗?像现在已弃用的弹簧测试@NotTransactional之类的东西可以与上面的选项 2 一起使用。

大约三年前有人问过一个非常相似的问题。既然 Spring 发生了很多事情,那么我们还有其他选择吗?

尽管它很整洁,但自定义注释答案并没有解决这个问题。

我的问题可以总结为:

如何配置事务而不必重写所有事务方法只指定事务管理器?

4

1 回答 1

2

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

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

Now, you simply autowire the last two classes into the refactored AbstractService, which just delegates an incoming method call to the implementation that was moved into one of the newly created classes.

于 2013-02-07T21:04:08.867 回答