不要在事务方法中覆盖 运行 的事务方法
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.
Execute non-transactionally, suspend the current transaction if one
exists. Analogous to EJB transaction attribute of the same name.
请务必通读共享的文档以了解此传播行为的限制。
希望这有帮助
我在某个地方问过这个问题,
假设我有一个方法 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.
Execute non-transactionally, suspend the current transaction if one exists. Analogous to EJB transaction attribute of the same name.
请务必通读共享的文档以了解此传播行为的限制。 希望这有帮助