对于最新的稳定版本,请使用 Spring Framework 6.2.0spring-doc.cadn.net.cn

事务传播

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

在 Spring 管理的事务中,请注意 physical 和 logical transactions 的 Barrier 事务,以及 PROPAGATION 设置如何应用于此差异。spring-doc.cadn.net.cn

理解PROPAGATION_REQUIRED

需要 tx prop

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

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

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

但是,在内部事务范围设置仅回滚标记的情况下, outer 事务尚未决定回滚本身,因此 rollback (静默地 triggered by the inner transaction scope)是意外的。相应的UnexpectedRollbackException在那个时候被抛出。这是预期行为,因此 事务的调用者永远不会被误导认为提交是 在它真的没有的时候表演。因此,如果内部事务(其中外部调用者 不知道)以静默方式将事务标记为仅回滚,外部调用方仍 调用 commit。外部调用方需要接收UnexpectedRollbackException自 清楚地指示已执行回滚。spring-doc.cadn.net.cn

理解PROPAGATION_REQUIRES_NEW

tx prop 需要新的

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

附加到外部事务的资源将保持绑定状态,而 内部事务获取自己的资源,例如新的 Database Connection。 这可能会导致连接池耗尽,并可能导致死锁,如果 多个线程具有活动的外部事务并等待获取新连接 对于他们的内部交易,矿池无法分发任何此类内部 连接。请勿使用PROPAGATION_REQUIRES_NEW除非你的连接池 的大小适当,至少超过并发线程数 1。

理解PROPAGATION_NESTED

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