问题描述
如果 REQUIRED
传播,当调用方法本身是transactionnal时,如果它们不同,当前方法是否会覆盖封闭的事务属性(例如rollbackFor)?
In the case of REQUIRED
propagation when the caller method itself is transactionnal does the current method overrides enclosing transaction properties (for example rollbackFor) if they are different ?
插图:
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() {
[...]
}
}
编辑:
好吧,我想避免琐碎的超出范围的答案,所以我们要清楚我知道弹簧传播处理。
Well, i'd like to avoid trivial out of scope answers, so let's be clear, I'am aware of spring propagation handling.
如果你不是,下面是文件的相关部分,我只想澄清关于第一部分的内容。我上面的例子:
If you're not, below is the relevant part of the documentation, I just would like to clarify the first part regarding my example above :
当传播设置为PROPAGATION_REQUIRED时,为应用了
的设置的每个方法创建逻辑
事务范围。每个这样的逻辑事务范围可以单独确定
仅回滚状态,外部事务范围
在逻辑上独立于内部事务范围。
课程中,如果是标准PROPAGATION_REQUIRED行为,所有这些
范围将映射到同一物理事务。因此,内部事务范围中的
仅回滚标记确实会影响
外部事务实际提交的机会(正如您所期望的那样
)。
When the propagation setting is PROPAGATION_REQUIRED, a logical transaction scope is created for each method upon which the setting is applied. Each such logical transaction scope can determine rollback-only status individually, with an outer transaction scope being logically independent from the inner transaction scope. Of course, in case of standard PROPAGATION_REQUIRED behavior, all these scopes will be mapped to the same physical transaction. So a rollback-only marker set in the inner transaction scope does affect the outer transaction’s chance to actually commit (as you would expect it to).
但是,在内部事务作用域设置
仅回滚标记的情况下,外部事务尚未决定
回滚本身,因此回滚(静默触发)由内部
交易范围)是出乎意料的。此时抛出相应的
UnexpectedRollbackException。这是预期的
行为,因此事务的调用者永远不会被误导为
,假设在实际上没有执行提交。因此,如果
内部事务(外部调用者不知道)静默地
将事务标记为仅回滚,则外部调用者仍然调用
commit。外部调用者需要收到一个
UnexpectedRollbackException,以清楚地表明回滚是
代替。
However, in the case where an inner transaction scope sets the rollback-only marker, the outer transaction has not decided on the rollback itself, and so the rollback (silently triggered by the inner transaction scope) is unexpected. A corresponding UnexpectedRollbackException is thrown at that point. This is expected behavior so that the caller of a transaction can never be misled to assume that a commit was performed when it really was not. So if an inner transaction (of which the outer caller is not aware) silently marks a transaction as rollback-only, the outer caller still calls commit. The outer caller needs to receive an UnexpectedRollbackException to indicate clearly that a rollback was performed instead.
My问题可以改写为:
My question can be reworded as this :
逻辑事务范围是否包含事务属性?
Does the logical transaction scope holds the transaction properties ?
推荐答案
所以,我设置了一个测试用例,简短的回答是肯定的。
So, I set up a test case, the short answer is yes.
事务逻辑范围包含事务属性,其边界确实是带注释的方法。
The transaction logical scope holds the transaction properties and its boundaries are indeed the annotated method ones.
因此,即使两种方法的基础物理事务相同,逻辑属性也适用于每种方法,而内部方法可以强制执行回滚外部方法事务。
如果最后一次触发提交,则会导致UnexpectedRollbackException。
So even if the underlying physical transaction is the same for both methods, the logical properties are proper to each method and the inner method can so force the rollback of the outer method transaction.If this last trigger a commit however it will lead to a UnexpectedRollbackException.
cf。 Spring TransactionInterceptor(评论是我的)
cf. Spring TransactionInterceptor (comments are mine)
try {
retVal = invocation.proceed();
}
catch (Throwable ex) {
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
completeTransactionAfterThrowing():
completeTransactionAfterThrowing() :
// txinfo is proper to the invocation target method
if (txInfo.transactionAttribute.rollbackOn(ex)) {
try {
txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
}
AbstractPlatformTransactionManager.processRollback():
AbstractPlatformTransactionManager.processRollback() :
else if (status.isNewTransaction()) { //requiresnew
doRollback(status);
}
else if (status.hasTransaction()) { //requiered
[...]
doSetRollbackOnly(status);
}
}
这篇关于Spring @Transactional Annotation属性优先级/继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!