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

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

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