如果是REQUIRED
当调用方方法本身是事务性的时,如果它们不同,当前方法是否会覆盖封闭的事务属性(例如 rollbackFor)?
插图 :
Class A {
@Transactional(propagation = Propagation.REQUIRED,
rollbackFor = { SomeException.class})
void foo() {
try {
b.bar();
} catch (OtherException e) {
// is the transaction marked as rollback-only at this point ?
}
}
}
Class B {
@Transactional(propagation = Propagation.REQUIRED,
rollbackFor = { OtherException.class})
void bar() {
[...]
}
}
edit :
好吧,我想避免琐碎的超出范围的答案,所以让我们明确一下,我知道弹簧传播处理。
如果您不是,下面是文档的相关部分,我只想澄清有关上面示例的第一部分:
PROPAGATION_REQUIRED
当传播设置为 PROPAGATION_REQUIRED 时,逻辑
为设置所基于的每个方法创建事务范围
应用。每个这样的逻辑事务范围可以确定
仅回滚状态,具有外部事务范围
逻辑上独立于内部事务范围。的
当然,在标准 PROPAGATION_REQUIRED 行为的情况下,所有这些
范围将映射到同一物理事务。所以一个
内部事务范围中设置的仅回滚标记确实会影响
外部事务实际提交的机会(正如您所期望的那样)
它到)。
但是,在内部事务范围设置的情况下
仅回滚标记,外部事务尚未决定
回滚本身,因此回滚(由内部默默触发)
交易范围)是意想不到的。对应的一个
此时会引发 UnexpectedRollbackException。这是预期的
行为,以便交易的调用者永远不会被误导
假设已执行提交,但实际并未执行。所以如果一个
内部事务(外部调用者不知道)默默地进行
将事务标记为仅回滚,外部调用者仍然调用
犯罪。外部调用者需要接收一个
UnexpectedRollbackException 清楚地表明发生了回滚
代替执行。
我的问题可以改写为:
逻辑事务范围是否保存事务属性?
所以,我设置了一个测试用例,简短的答案是肯定的。
事务逻辑范围保存事务属性,其边界实际上是带注释的方法边界。
因此,即使两种方法的底层物理事务相同,逻辑属性也适用于每个方法,并且内部方法可以强制回滚外部方法事务。
如果最后触发提交,则会导致 UnexpectedRollbackException。
参见Spring TransactionInterceptor(评论是我的)
try {
retVal = invocation.proceed();
}
catch (Throwable ex) {
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
CompleteTransactionAfterThrowing() :
// txinfo is proper to the invocation target method
if (txInfo.transactionAttribute.rollbackOn(ex)) {
try {
txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
}
AbstractPlatformTransactionManager.processRollback() :
else if (status.isNewTransaction()) { //requiresnew
doRollback(status);
}
else if (status.hasTransaction()) { //requiered
[...]
doSetRollbackOnly(status);
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)