0

在下面的示例中,我成功地落入了终点mandatory()——尽管两个互斥的@Transactional注解之一必须抛出异常:无论是Propagation.NEVER还是Propagation.MANDATORY. 但是代码执行成功。

怎么可能?!

我的一些(不是全部)服务受到影响,我想了解原因。

class NewService {

static transactional = true

boolean process() {
    return never()
}

@Transactional(propagation = Propagation.NEVER)
boolean never() {
    return mandatory()
}

@Transactional(propagation = Propagation.MANDATORY)
boolean mandatory() {
    // successfully breakpointed here o_O
    return true
}
}

圣杯 2.2.0

4

2 回答 2

4

看起来您正在绕过 bean 代理,正如Burt Beckwith(幻灯片 23)所说的“无意中绕过 bean 代理”。

您需要获取代理并在其上执行您的方法。

@Transactional(propagation = Propagation.NEVER)
boolean never() {
    def myproxy= grailsApplication.mainContext.newService
    return myproxy.mandatory() 
}

@Transactional(propagation = Propagation.MANDATORY)
boolean mandatory() {
    // successfully breakpointed here o_O
    return true
}
于 2013-08-14T13:40:53.670 回答
2

Spring 声明式事务是基于 AOP 的。Spring AOP 是基于代理的。这意味着当通过代理从另一个bean调用 bean 时,会读取并考虑事务注释:

Bean A --> injected transactional proxy --> Bean B

在您的情况下,您直接调用同一个 bean 的另一个方法。事务代理因此不知道这个调用,因此不能强制事务的存在:

Bean A --> this
于 2013-08-14T13:32:44.900 回答