不要在事务方法中覆盖 运行 的事务方法

Don't cover a method in transaction that is running inside a transactional method

我在某个地方问过这个问题,

假设我有一个方法 A,它是 运行 在事务中使用 @transactional , 如果存在从该事务方法调用的方法 B,则默认情况下这也将是同一事务中的 运行。

所以,问题是 B 不在交易范围内怎么办, 如何避免B.

的交易

您必须使用以下模式来获得您想要的结果:执行 A,如果 B 需要 A 的结果,您可以将其发送到非事务上下文中。

void myFunction() {
        Object result = myTransactionalClass.A();
        B(result);
}

请注意,既然您在问这个问题(您不希望 B() 是事务性的),那么提到的代码肯定会起作用。

根据评论说这两种方法都在同一个 class(自调用)中,下面的代码可以工作。

 @Service
public class TestService {

    @Autowired // Self autowiring
    TestService service;

    @Transactional
    public void methodA() {
        service.methodB();
    }

    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void methodB() {
        //...
    }
}

service.methodA() 的外部调用将初始化事务,对 service.methodB() 的自调用将导致 methodB() 也是同一事务的一部分,即使它被注释为不参与交易。 为了解决这个问题,我们在该实例上自动装配并调用 methodB()。这将导致 methodB() 的交易配置被接受。

以下是自动装配的原因,documentation

In proxy mode (which is the default), only external method calls coming in through the proxy are intercepted. This means that self-invocation (in effect, a method within the target object calling another method of the target object) does not lead to an actual transaction at runtime even if the invoked method is marked with @Transactional.

参考:Propagation.NOT_SUPPORTED

Execute non-transactionally, suspend the current transaction if one exists. Analogous to EJB transaction attribute of the same name.

请务必通读共享的文档以了解此传播行为的限制。 希望这有帮助