Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring@Transactional继承规则_Java_Spring_Service_Transactional - Fatal编程技术网

Java Spring@Transactional继承规则

Java Spring@Transactional继承规则,java,spring,service,transactional,Java,Spring,Service,Transactional,我有一组@Servicebean,它们从抽象类继承核心功能。我用@Service和@Transactional标记了每个具体的子类服务。抽象超类包含每个服务的公共入口点方法。换言之,我有一些类似于以下内容: abstract class AbstractService { public void process() { // Do common initialisation code here processSpecific(); //

我有一组
@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
    }
}
每个具体子类服务中的特定代码对DAO层进行多次调用,以对数据库进行更改,将
REQUIRED
作为事务传播类型

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

但是,如果我用
@Transactional
注释抽象超类,那么事务将正确创建,并且对DAO层的子调用都将参与当前事务


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

您是否阅读了该部分以及如何使用配置它


另一个有趣的方面是Spring建议您应该(与注释接口相反)。

来自Spring事务文档

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

尽管您在具体实现中有@Transactional,并且您正在调用流程方法,该方法实际上是注释中的事务性方法,但是在子类中调用processSpecific的流程方法由于此内部调用而不是事务性的


研究编织。

这是一个老问题。但我遇到了类似的情况,并在当前的javadoc中找到了@Transactional注释的解释:

在类级别,此注释作为默认值应用于所有 声明类及其子类的方法。请注意,确实如此 不适用于类层次结构上的祖先类;方法需要 在本地重新声明以参与子类级别 注释

因此,当使用继承和类级注释时,如果超类包含任何应该是事务性的公共方法,或者由需要是事务性的子类实现的do-call方法,则应该注释超类而不是子类

从没有超类的超类中的方法调用由子类实现并注释为@Transactional的方法,或者调用注释为@Transactional的方法是一个bug。 如果两者都有注释,但注释上的属性不一致,这也是一个bug


在一个好的设计中,由子类实现的超类中的虚拟方法应该只由超类使用,因为它们应该始终具有范围保护,并且在子类中不需要任何@Transactional注释,但这似乎并没有涵盖这一点。我有完全相同的问题-在我的情况下,我甚至没有委托类似于调用DAO的
processSpecific()
,即使标记子类@Transactional并没有使流程看起来有一个Txn openYes,如上所述,我已经阅读了文件中的所有章节,其中似乎没有一节适用于本案例。我的抽象超类不是一个接口,它是由实际的具体子类继承的代码。也许您可以引用您认为适用于我的示例的文档部分。如果您想确保您的DAO始终参与现有事务(由您的服务启动),您应该将DAO配置为@Transactional(传播=),因为如果不存在事务,则使用将创建新事务。是,这将是我们将来发现这些问题的一种方法,但它仍然不能解释继承规则是什么。但是代理不是“FirstSpecificService”的一个实例吗?在这种情况下,系统将调用该实例的外部“process”方法,实例本身被标记为
@Transactional
。我完全理解标记为
@Transactional
的内部私有或受保护方法不会影响事务,但这不是我所拥有的。我的整个bean被标记为
@Transactional
。不,如果从内部方法调用它,它将不会是事务性的。首先,当您从外部调用process方法时,代理实例是事务控制的,当process方法调用processSpecific时,spring不知道事务,因为切入点是在代理对象上而不是在子类processSpecific方法上进行的。我们也遇到了同样的问题,我们添加了加载时编织,一切都正常了。它将如何更改这些(人为的)示例服务的代码?当您使用-javaagent:启动应用程序时,您必须添加到上下文文件并提供-javaagent:。我认为这个spring代理在较新的spring版本中是org.springframework.instrument-3.1.1.RELEASE.jar。所以应该是-javaagent:。如果您正在开发webapp并使用tomcat,则有不同的步骤