[英]Exception on batch processing UnexpectedRollbackException - Transaction rolled back
I am getting the below exception when doing a batch processing 批处理时出现以下异常
encountered an error.org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:252)
at java.util.concurrent.FutureTask.get(FutureTask.java:111)
Could someone help me with what might be the issue? 有人可以帮助我解决什么问题吗?
Thanks. 谢谢。
Probably you have a checked exception somewhere in one of your beans that you catch in another one, but the transaction advice of spring notices it and will mark the transaction for rollback. 可能您在一个bean中的某个位置某个地方有一个已检查的异常,而在另一个bean中却被捕获,但是spring的事务处理通知会注意到该异常,并将该事务标记为回滚。
You can play with the noRollBackFor property of the Transactional annotation. 您可以使用Transactional批注的noRollBackFor属性。
The possibility of getting this exception in Spring-managed environments is when the transaction propagation is set to REQUIRED
: 在Spring托管环境中,当事务传播设置为
REQUIRED
时,可能会出现此异常:
<tx:method name="do*" propagation="REQUIRED" />
Consider a scenario as this: 考虑这样的情况:
Caller -------> [Transactional Method1(m1)] ----------> [Transactional Method2(m2)]
呼叫者-------> [交易方法1(m1)] ----------> [交易方法2(m2)]
In Spring-managed environments, there is a difference between logical
and physical
transactions. 在Spring管理的环境中,
logical
事务和physical
事务之间是有区别的。 A logical
transaction scope is created for each method upon which this setting is applied. 将为应用此设置的每种方法创建一个
logical
事务作用域。 The logical
transaction scope for method m1
is different from m2
. 方法
m1
的logical
事务范围不同于m2
。 Each logical
transaction can determine its own rollback-only status individually. 每个
logical
事务可以单独确定其自己的仅回滚状态。 And with this setting, an outer transaction scope (m1's scope) is logically independent from the inner transaction scope (m2's scope). 通过此设置,外部事务范围(m1的范围)在逻辑上独立于内部事务范围(m2的范围)。
But all these scopes are mapped to the same physical
transaction. 但是所有这些范围都映射到同一
physical
事务。 So, if the inner transaction is marked for rollback, it effects the outer transaction's chance to commit (even if there is no exception thrown from the the outer transaction). 因此,如果将内部事务标记为回滚,则会影响外部事务的提交机会(即使外部事务没有抛出异常)。
Now if there is an exception thrown from inner transaction and it is marked for rollback. 现在,如果内部事务抛出异常,则将其标记为回滚。 But there is no exception thrown from outer transaction, so it has not decided on the rollback itself, and so the rollback (silently triggered by the inner transaction scope) is unexpected.
但是外部事务不会引发任何异常,因此它尚未决定回滚本身,因此回滚(由内部事务作用域无提示触发)是意外的。 And a corresponding
UnexpectedRollbackException
is thrown at that point. 并在此时引发相应的
UnexpectedRollbackException
。
So if an inner transaction (of which the outer caller is not aware) silently marks a transaction as rollback-only, the outer caller receives an UnexpectedRollbackException
if it still calls commit. 因此,如果内部事务(外部调用者不知道)将其事务静默地标记为仅回滚事务,则外部调用者如果仍调用commit,则会收到
UnexpectedRollbackException
。 This is an indication to the outer caller that a rollback was performed instead of a commit. 这是向外部调用者指示执行回滚而不是提交的指示。 And this an expected behavior to let the caller of a transaction know that there was an exception and the the transaction was rolled back.
这是一种预期的行为,它使事务的调用者知道存在异常,并且该事务已回滚。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.