4

进行批处理时出现以下异常

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)

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

谢谢。

4

2 回答 2

7

可能您的一个 bean 中某处有一个已检查异常,您在另一个 bean 中捕获该异常,但 spring 的事务建议会注意到它并将标记事务以进行回滚。

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

于 2013-10-25T18:11:05.067 回答
5

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

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

考虑这样一个场景:

调用者-------> [事务方法1(m1)] ----------> [事务方法2(m2)]

logical在 Spring 管理的环境中,和physical事务是有区别的。logical为应用此设置的每个方法创建一个事务范围。方法的logical交易范围m1不同于m2. 每个logical事务都可以单独确定自己的仅回滚状态。并且通过此设置,外部事务范围(m1 的范围)在逻辑上独立于内部事务范围(m2 的范围)。

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

现在,如果内部事务抛出异常并将其标记为回滚。但是外部事务没有抛出异常,所以它还没有决定回滚本身,所以回滚(由内部事务范围静默触发)是意外的。并UnexpectedRollbackException在该点抛出相应的。

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

于 2013-10-27T14:39:36.463 回答