批处理异常UnexpectedRollbackException - 事务回滚

时间:2013-10-18 06:50:20

标签: java spring

我在进行批处理时遇到以下异常

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)

有人可以帮我解决可能存在的问题吗?

感谢。

2 个答案:

答案 0 :(得分:6)

你可能在另一个bean中的某个bean中有一个已检查的异常,但是spring的事务通知会注意到它并将标记该事务以进行回滚。

您可以使用Transactional注释的noRollBackFor属性。

答案 1 :(得分:5)

在Spring管理的环境中获得此异常的可能性是事务传播设置为REQUIRED时:

<tx:method name="do*" propagation="REQUIRED" />

考虑一个场景:

  

来电者-------&gt; [交易方法1(m1)] ----------&gt; [事务   方法2(平方米)]

在Spring管理的环境中,logicalphysical交易之间存在差异。为应用此设置的每个方法创建logical事务范围。方法logical的{​​{1}}交易范围与m1不同。每个m2事务可以单独确定其自己的仅回滚状态。使用此设置,外部事务范围(m1的范围)在逻辑上独立于内部事务范围(m2的范围)。

但是所有这些范围都映射到相同的logical事务。因此,如果内部事务被标记为回滚,则它会影响外部事务的提交机会(即使外部事务没有抛出异常)。

现在,如果从内部事务抛出异常并且标记为回滚。但是外部事务没有抛出异常,所以它还没有决定回滚本身,因此回滚(由内部事务范围静默触发)是意外的。此时会抛出相应的physical

因此,如果内部事务(外部调用者不知道)默认将事务标记为仅回滚,则外部调用者如果仍调用commit,则会收到UnexpectedRollbackException。这表示外部调用者执行了回滚而不是提交。这是一个预期的行为,让事务的调用者知道存在异常并且事务被回滚。