@StijnGeukens 很接近。 Spring 实际上使用代理来处理事务,并且通过default http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/transaction/annotation/Propagation.html#REQUIRED从一个事务方法调用另一个事务方法不会导致创建新事务。然而,在这种情况下,传播被明确设置为需要一个新的 http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/transaction/annotation/Propagation.html#REQUIRES_NEW正在创建交易。应该创建 2 个事务:
T1: create
T2: create
Exception occurs here
T2: commit
T1: commit
正如您所看到的,异常发生在任一事务到达其提交点之前。由于它没有被处理First
,执行永远不会到达提交点T1
。这将导致顶级事务被回滚。
但是,您可以在以下位置处理异常:First
但它仍然行不通。从我上面链接到的文档:
Note: Actual transaction suspension will not work out-of-the-box on all transaction managers. This in particular applies to JtaTransactionManager, which requires the javax.transaction.TransactionManager to be made available it to it (which is server-specific in standard J2EE).
So your propagation=REQUIRES_NEW
很可能实际上并没有按照它所说的去做,因为它不喜欢你的TransactionManager
。欢迎来到春天。
Update来自Jpa事务管理器 http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/orm/jpa/JpaTransactionManager.html docs:
在 JDBC 3.0 上,该事务管理器通过以下方式支持嵌套事务
JDBC 3.0 保存点。这AbstractPlatformTransactionManager.setNestedTransactionAllowed(boolean)
"nestedTransactionAllowed"
不过,标志默认为“false”,如
嵌套事务仅适用于 JDBC 连接,而不适用于
JPA EntityManager 及其缓存对象。您可以手动设置
如果您想使用嵌套事务进行 JDBC 访问,则标记为“true”
参与 JPA 事务的代码(前提是您的 JDBC
驱动程序支持保存点)。注意JPA本身不支持
嵌套事务!因此,不要期望 JPA 访问代码
在语义上参与嵌套事务。
这非常令人困惑,但我认为它的意思是,如果您设置提到的标志,您将能够使用嵌套事务,这是使用 JDBC 3.0 的一项功能实现的。因此,请确保您的驱动程序符合该规范。