java Spring @Transactional 继承规则

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9918594/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 22:54:03  来源:igfitidea点击:

Spring @Transactional inheritance rules

javaspringservicetransactional

提问by DuncanKinnear

I have a set of @Servicebeans which inherit core functionality from an abstract class. I marked each of the concrete sub-class services with @Serviceand @Transactional. The abstract super class contains the public entry point method for each of these services. In other words, I have something similar to the following:

我有一组@Service从抽象类继承核心功能的bean。我用@Service和标记了每个具体的子类服务@Transactional。抽象超类包含每个这些服务的公共入口点方法。换句话说,我有类似的东西:

abstract class AbstractService {

    public void process() {
        // Do common initialisation code here
        processSpecific();
        // Do common completion code here
    }

    abstract protected void processSpecific();
}


@Service @Transactional
public class FirstSpecificService extends AbstractService {
    protected void processSpecific() {
        // Do specific processing code here
    }
}


@Service @Transactional
public class SecondSpecificService extends AbstractService {
    protected void processSpecific() {
        // Do different specific processing code here
    }
}

The specific code in each concrete sub-class service makes multiple calls to the DAO layer to make changes to the database, which have REQUIREDas the transactional propagation type.

每个具体的子类服务中的特定代码都会多次调用 DAO 层以对数据库进行更改,这些更改REQUIRED作为事务传播类型。

Now with the services defined as above, I discovered that there was no current transaction inside any of the code of these concrete sub-class services, and each call to the DAO layer was creating a new transaction, doing the changes, committing the transaction and returning.

现在有了上面定义的服务,我发现在这些具体子类服务的任何代码中都没有当前事务,每次调用 DAO 层都在创建一个新事务,进行更改,提交事务和回来。

However, if I annotate the abstract super-class with @Transactional, then a transaction iscreated properly, and the sub-calls to the DAO layer all participate in the current transaction.

但是,如果我注释抽象超类@Transactional,那么交易正确创建,和子调用DAO层所有参与当前事务。

So my question is, what are the rules for inheriting the @Transactionalbehaviour? Why does Spring not use the @Transactionalon the concrete sub-class services that it is actually instantiating? Does the @Transactionalneed to be on the super-class in this case because that is where the public entry-point method is?

所以我的问题是,继承@Transactional行为的规则是什么?为什么 Spring 不在@Transactional它实际实例化的具体子类服务上使用?@Transactional在这种情况下是否需要在超类上,因为这是公共入口点方法所在的位置?

采纳答案by Kathir

From the spring transaction documentation,

从 spring 交易文档中,

Note: In proxy mode (which is the default), only 'external' method calls coming in through the proxy will be intercepted. This means that 'self-invocation', i.e. a method within the target object calling some other method of the target object, won't lead to an actual transaction at runtime even if the invoked method is marked with @Transactional!

注意:在代理模式下(默认),只有通过代理进入的“外部”方法调用才会被拦截。这意味着“自调用”,即目标对象中的方法调用目标对象的其他方法,即使被调用的方法用@Transactional 标记,也不会在运行时导致实际事务!

Even though you have the @Transactional on your concrete implementation and you are calling process method which is actually transactional by your annotation, but the process method calling processSpecific on your sub class is not transactional because of this internal call.

即使你在你的具体实现上有 @Transactional 并且你正在通过你的注释调用实际上是事务性的 process 方法,但是由于这个内部调用,在你的子类上调用 processSpecific 的 process 方法不是事务性的。

Look into Weaving.

看看织布。

回答by matsev

Did you read the part about transaction propagationand how it can be configured using @Transactional?

您是否阅读了有关事务传播以及如何使用@Transactional对其进行配置的部分?

Another area of interest is that Spring recommends that you should annotate concrete classes(as opposes to annotate interfaces).

另一个有趣的领域是 Spring 建议您应该注释具体类(与注释接口相反)。