- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我对这个异常的了解来自 Spring 的 documentation以及一些论坛帖子,其中结霜的开发人员粘贴了大量的堆栈跟踪,但没有回复。
来自 Spring 的文档:
Thrown when an attempt to commit a transaction resulted in an unexpected rollback
我想一劳永逸地理解
究竟是什么原因造成的?
如何避免?有什么最佳做法可以避免吗?
最佳答案
我发现这是在回答剩下的问题:https://jira.springsource.org/browse/SPR-3452
I guess we need to differentiate between 'logical' transaction scopes and 'physical' transactions here...
What PROPAGATION_REQUIRED creates is a logical transaction scope for each method that it gets applied to. Each such logical transaction scope can individually decide on rollback-only status, with an outer transaction scope being logically independent from the inner transaction scope. Of course, in case of standard PROPAGATION_REQUIRED behavior, they 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. However, since the outer transaction scope did not decide on a rollback itself, the rollback (silently triggered by the inner transaction scope) comes unexpected at that level - which is why an UnexpectedRollbackException gets thrown.
PROPAGATION_REQUIRES_NEW, in contrast, uses a completely independent transaction for each affected transaction scope. In that case, the underlying physical transactions will be different and hence can commit or rollback independently, with an outer transaction not affected by an inner transaction's rollback status.
PROPAGATION_NESTED is different again in that it uses a single physical transaction with multiple savepoints that it can roll back to. Such partial rollbacks allow an inner transaction scope to trigger a rollback for its scope, with the outer transaction being able to continue the physical transaction despite some operations having been rolled back. This is typically mapped onto JDBC savepoints, so will only work with JDBC resource transactions (Spring's DataSourceTransactionManager).
To complete the discussion: UnexpectedRollbackException may also be thrown without the application ever having set a rollback-only marker itself. Instead, the transaction infrastructure may have decided that the only possible outcome is a rollback, due to constraints in the current transaction state. This is particularly relevant with XA transactions.
As I suggested above, throwing an exception at the inner transaction scope, then catching that exception at the outer scope and translating it into a silent setRollbackOnly call there should work for your scenario. A caller of the outer transaction will never see an exception then. Since you only worry about such silent rollbacks because of special requirements imposed by a caller, I would even argue that the correct architectural solution is to use exceptions within the service layer, and to translate those exceptions into silent rollbacks at the service facade level (right before returning to that special caller).
Since your problem is possibly not only about rollback exceptions, but rather about any exceptions thrown from your service layer, you could even use standard exception-driven rollbacks all the way throughout you service layer, and then catch and log such exceptions once the transaction has already completed, in some adapting service facade that translates your service layer's exceptions into UI-specific error states.
Juergen
关于java - UnexpectedRollbackException - 完整的场景分析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2007097/
我的 spring 应用程序中出现 UnexpectedRollbackException。这是我的存储库类 @Repository public class MyDao { @Persist
我在 spring 的事务管理中有以下奇怪的场景: 我有一个调用方法 B 的方法 A,方法 B 调用方法 C,每个方法都在不同的类中。方法 B 和 C 都用事务包装。两者都使用 PROPAGATION
我对这个异常的了解来自 Spring 的 documentation以及一些论坛帖子,其中结霜的开发人员粘贴了大量的堆栈跟踪,但没有回复。 来自 Spring 的文档: Thrown when an
我有两个类: @Service @Transaction class A { public void method1() { private B; try {
我在进行批处理时遇到以下异常 encountered an error.org.springframework.transaction.UnexpectedRollbackException: Tra
当使用@Transactional注释方法并且存在运行时异常时,spring会吃掉该异常并抛出: org.springframework.transaction.UnexpectedRollbackE
我的服务“duplicateContract”出现 hibernate 回滚异常 Caused by: org.springframework.transaction.UnexpectedRollba
我是一名优秀的程序员,十分优秀!