如果REQUIRED
传播时调用方法本身是transactionnal,那么当前方法是否会覆盖封闭事务属性(例如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() {
[...]
}
}
修改:
好吧,我想避免琐碎的范围答案,所以我们要清楚,我知道弹簧传播处理。
如果你不是,下面是文档的相关部分,我只想澄清关于我上面例子的第一部分:
PROPAGATION_REQUIRED
当传播设置为PROPAGATION_REQUIRED时,为逻辑 为设置所在的每个方法创建事务范围 应用。每个这样的逻辑事务范围都可以确定 仅具有回滚状态,具有外部事务范围 在逻辑上独立于内部事务范围。的 当然,在标准的PROPAGATION_REQUIRED行为的情况下,所有这些 范围将映射到同一物理事务。那么一个 内部事务范围中设置的仅回滚标记确实会影响 外部交易实际提交的机会(正如您所期望的那样) 它来)。
但是,在内部事务范围设置的情况下 rollback-only标记,外部事务还没有决定 回滚本身,以及回滚(由内部静默触发) 事务范围)是意外的。相应的 此时抛出UnexpectedRollbackException。这是预料之中的 行为,以便永远不会误导交易的调用者 假设在确实没有执行提交时。所以,如果一个 内部事务(外部调用者不知道)默默地 将事务标记为仅回滚,外部调用者仍然调用 承诺。外部呼叫者需要接收 UnexpectedRollbackException清楚地表明回滚是 相反。
我的问题可以改写为:
逻辑事务范围是否包含事务属性?
答案 0 :(得分:2)
所以,我设置了一个测试用例,简短的回答是肯定的。
事务逻辑范围包含事务属性,其边界确实是带注释的方法。
因此,即使两个方法的底层物理事务都相同,逻辑属性也适用于每个方法,而内部方法可以强制回滚外部方法事务。 如果最后一次触发提交,则会导致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);
}
}
答案 1 :(得分:0)
参见spring documentation的第16.5.7节。 即使内部方法在事务上下文中被调用时也使用REQUIRED进行注释,它将映射到相同的物理事务。
答案 2 :(得分:0)
在我对规范的理解中,我会在这个例子中说:
Class A {
@Transactional(propagation = Propagation.REQUIRED,
rollbackFor = { SomeException.class})
void foo() {
try {
b.bar();
} catch (OtherException e) {
// the transaction is marked as rollback-only by the inner call as it thrown an OtherException
// XXX --- or not if inner logical scope does not handle overridden property 'rollbackFor' ? ---
// anyway, we avoid UnexpectedRollbackException by enforcing physical rollback to outter scope programmatically, by throwing :
throw new SomeExeption(e);
}
}
}
Class B {
@Transactional(propagation = Propagation.REQUIRED,
rollbackFor = { OtherException.class})
void bar() {
[...]
}
}
所以我们可以将问题重新表述为:覆盖“rollbackFor”属性是由内部逻辑事务范围管理处理的吗?
顺便说一下,您使用的确切事务管理器类和版本是什么?