此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Framework 6.2.0! |
事务传播
本节描述了 Spring 中事务传播的一些语义。注意 本节不是对 Transaction Propagation 的适当介绍。相反,它 详细介绍了 Spring 中有关事务传播的一些语义。
在 Spring 管理的事务中,请注意 physical 和 logical transactions 的 Barrier 事务,以及 PROPAGATION 设置如何应用于此差异。
理解PROPAGATION_REQUIRED

PROPAGATION_REQUIRED
强制执行物理事务,无论是在本地为当前的
scope(如果尚不存在交易或参与现有的 'outer' 交易)
为更大的范围定义。这是常见调用堆栈安排中的一个很好的默认值
在同一线程中(例如,委托给多个存储库方法的服务门面
其中所有底层资源都必须参与服务级事务)。
默认情况下,参与的事务会加入外部范围
静默忽略本地隔离级别、超时值或只读标志(如果有)。
考虑将validateExistingTransactions flag 设置为true 在您的交易中
manager 如果您希望在参与
具有不同隔离级别的现有事务。这种不宽容的模式也
拒绝只读不匹配(即尝试参与的内部读写事务
在只读外部作用域中)。 |
当传播设置为PROPAGATION_REQUIRED
、逻辑事务范围
为应用该设置的每种方法创建。每个这样的逻辑
transaction 作用域可以单独确定仅回滚状态,并使用外部
事务范围在逻辑上独立于内部事务范围。
在标准PROPAGATION_REQUIRED
行为,所有这些范围都是
映射到同一 Physical 事务。因此,在内部
事务范围确实会影响外部事务实际提交的机会。
但是,在内部事务范围设置仅回滚标记的情况下,
outer 事务尚未决定回滚本身,因此 rollback (静默地
triggered by the inner transaction scope)是意外的。相应的UnexpectedRollbackException
在那个时候被抛出。这是预期行为,因此
事务的调用者永远不会被误导认为提交是
在它真的没有的时候表演。因此,如果内部事务(其中外部调用者
不知道)以静默方式将事务标记为仅回滚,外部调用方仍
调用 commit。外部调用方需要接收UnexpectedRollbackException
自
清楚地指示已执行回滚。
理解PROPAGATION_REQUIRES_NEW

PROPAGATION_REQUIRES_NEW
,与PROPAGATION_REQUIRED
,始终使用
每个受影响的事务范围的独立物理事务,从不
参与 outer scope 的现有事务。在这样的安排下,
底层资源事务是不同的,因此可以提交或回滚
独立,外部事务不受内部事务回滚的影响
状态,并在内部事务完成后立即释放其锁。
这样一个独立的内部事务也可以声明自己的隔离级别 timeout,
和只读设置,并且不会继承外部事务的特征。
附加到外部事务的资源将保持绑定状态,而
内部事务获取自己的资源,例如新的 Database Connection。
这可能会导致连接池耗尽,并可能导致死锁,如果
多个线程具有活动的外部事务并等待获取新连接
对于他们的内部交易,矿池无法分发任何此类内部
连接。请勿使用PROPAGATION_REQUIRES_NEW 除非你的连接池
的大小适当,至少超过并发线程数 1。 |
理解PROPAGATION_NESTED
PROPAGATION_NESTED
使用具有多个 Savepoint 的单个物理事务
它可以回滚到。这种部分回滚允许内部事务范围
触发其范围的回滚,外部事务能够继续
尽管某些作已回滚,但 Physical Transaction 仍会丢失。此设置
通常映射到 JDBC 保存点,因此它仅适用于 JDBC 资源
交易。参见 Spring 的DataSourceTransactionManager
.