此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Framework 6.2.10spring-doc.cadn.net.cn

事务传播

本节描述 Spring 中事务传播的一些语义。 注意 本节不是对事务传播的正确介绍。相反,它详细介绍了有关 Spring 中事务传播的一些语义。spring-doc.cadn.net.cn

在 Spring 管理的事务中,请注意物理事务和逻辑事务之间的区别,以及传播设置如何应用于此差异。spring-doc.cadn.net.cn

理解PROPAGATION_REQUIRED

需要 TX 道具

PROPAGATION_REQUIRED强制执行物理事务,无论是在本地为当前事务如果尚不存在事务或参与现有的“外部”事务,则范围为更大的范围定义。这是常见调用堆栈安排中的一个很好的默认值在同一线程中(例如,委托给多个存储库方法的服务外观其中所有底层资源都必须参与服务级事务)。spring-doc.cadn.net.cn

默认情况下,参与事务会加入外部作用域静默忽略本地隔离级别、超时值或只读标志(如果有)。考虑将validateExistingTransactionsflag 到true在您的交易上如果您希望在参与隔离级别时拒绝隔离级别声明,则管理器具有不同隔离级别的现有事务。这种非宽松模式还拒绝只读不匹配(即尝试参与的内部读写事务在只读外部范围内)。

当传播设置为PROPAGATION_REQUIRED,一个逻辑事务范围为应用该设置的每个方法创建。每个这样的逻辑事务范围都可以单独确定仅回滚状态,外部事务范围在逻辑上独立于内部事务范围。在标准的情况下PROPAGATION_REQUIRED行为,所有这些作用域都是映射到同一个物理事务。因此,在内部transaction 作用域中设置的仅回滚标记确实会影响外部事务实际提交的机会。spring-doc.cadn.net.cn

但是,在内部事务作用域设置仅回滚标记的情况下,外部事务尚未决定回滚本身,因此回滚(静默地由内部事务作用域触发)是意外的。对应的UnexpectedRollbackException在这一点上被抛出。这是预期行为,因此事务的调用者永远不会被误导,认为提交是执行,而实际上没有执行。因此,如果内部事务(外部调用者不知道)静默地将事务标记为仅回滚,则外部调用者仍调用提交。外部调用者需要接收UnexpectedRollbackException自 清楚地指示已执行回滚。spring-doc.cadn.net.cn

理解PROPAGATION_REQUIRES_NEW

tx prop 需要新的

PROPAGATION_REQUIRES_NEW,与PROPAGATION_REQUIRED,始终使用独立的物理事务,用于每个受影响的事务范围,从不参与外部范围的现有事务。在这样的安排中,底层资源事务是不同的,因此可以提交或回滚独立,外部事务不受内部事务回滚状态的影响,并且内部事务的锁在完成后立即释放。这种独立的内部事务还可以声明自己的隔离级别、超时、和只读设置,而不继承外部事务的特征。spring-doc.cadn.net.cn

附加到外部事务的资源将保持绑定在那里,而 内部事务获取自己的资源,例如新的数据库连接。 这可能会导致连接池耗尽,如果出现以下情况,则可能导致死锁 多个线程具有活动的外部事务并等待获取新连接 对于他们的内部交易,池无法分发任何这样的内部交易 连接。请勿使用PROPAGATION_REQUIRES_NEW除非您的连接池 大小适当,至少超过并发线程数 1。

理解PROPAGATION_NESTED

PROPAGATION_NESTED使用具有多个保存点的单个物理事务 它可以回滚到。这种部分回滚让内部事务范围 触发其作用域的回滚,外部事务能够继续 尽管某些作已被回滚,但物理事务。此设置 通常映射到 JDBC 保存点,因此它仅适用于 JDBC 资源 交易。参见 Spring 的DataSourceTransactionManager.spring-doc.cadn.net.cn