什么是嵌套事务?

什么是嵌套事务?
       嵌套事务是一个外部事务的一个子事务,是一个外部事务的一个组成部分,当嵌套事务发生异常,而回滚,则会回复到嵌套事务的执行前的状态,相当于嵌套事务未执行。
如果外部事务回滚,则嵌套事务也会回滚!!!外部事务提交的时候,它才会被提交。
      
 PROPAGATION_REQUIRES_NEW 和 PROPAGATION_NESTED 的最大区别在于, PROPAGATION_REQUIRES_NEW 完全是一个新的事务, 而 PROPAGATION_NESTED 则是外部事务的子事务, 如果外部事务 commit, 潜套事务也会被 commit, 这个规则同样适用于 roll back. 

PROPAGATION_NESTED on the other hand starts a "nested" transaction, which is a true subtransaction of the existing one. What will happen is that a savepoint will be taken at the start of the nested transaction. íf the nested transaction fails, we will roll back to that savepoint. The nested transaction is part of of the outer transaction, so it will only be committed at the end of of the outer transaction. 

Nested transactions essentially allow to try some execution subpaths as subtransactions: rolling back to the state at the beginning of the failed subpath, continuing with another subpath or with the main execution path there - all within one isolated transaction, and not losing any previous work done within the outer transaction. 

For example, consider parsing a very large input file consisting of account transfer blocks: The entire file should essentially be parsed within one transaction, with one single commit at the end. But if a block fails, its transfers need to be rolled back, writing a failure marker somewhere. You could either start over the entire transaction every time a block fails, remembering which blocks to skip - or you mark each block as a nested transaction, only rolling back that specific set of operations, keeping the previous work of the outer transaction. The latter is of course much more efficient, in particular when a block at the end of the file fails. 


Juergen Hoeller 写道

Rolling back the entire transaction is the choice of the demarcation code/config that started the outer transaction. 

So if an inner transaction throws an exception and is supposed to be rolled back (according to the rollback rules), the transaction will get rolled back to the savepoint taken at the start of the inner transaction. The immediate calling code can then decide to catch the exception and proceed down some other path within the outer transaction. 

If the code that called the inner transaction lets the exception propagate up the call chain, the exception will eventually reach the demarcation code of the outer transaction. At that point, the rollback rules of the outer transaction decide whether to trigger a rollback. That would be a rollback of the entire outer transaction then. 

So essentially, it depends on your exception handling. If you catch the exception thrown by the inner transaction, you can proceed down some other path within the outer transaction. If you let the exception propagate up the call chain, it's eventually gonna cause a rollback of the entire outer transaction. 
### 事务嵌套的使用方法与行为 数据库中的 **nested transactions**(嵌套事务)是一种允许在一个事务内部启动另一个事务的功能。这种机制通常用于复杂的业务逻辑场景,其中某些操作可能需要独立提交或回滚而不影响外部事务的状态。 #### 嵌套事务的行为特点 1. 外部事务控制整体状态,而内部事务可以具有局部作用域[^2]。 2. 如果支持真正的嵌套事务,则只有当所有子事务都成功完成时,整个事务才会被标记为成功并最终提交[^3]。 3. 子事务的 `COMMIT` 并不会立即生效;它仅表示该部分工作已完成,但仍需等待父事务的整体提交才能永久化更改[^4]。 4. 若某个子事务失败并执行 `ROLLBACK`,则其修改会被撤销,但不影响其他已成功的兄弟子事务或父事务继续运行[^5]。 #### SQL Server 中的实现方式 在 Microsoft SQL Server 数据库管理系统里,通过设置 SAVEPOINT 来模拟嵌套事务的效果。SAVEPOINT 定义了一个恢复点,在此之后所做的任何变更都可以单独撤消,而无需终止整个大范围内的活动记录更新过程: ```sql BEGIN TRANSACTION OuterTran; -- Some operations here... BEGIN TRANSACTION InnerTran; INSERT INTO ExampleTable (ColumnA) VALUES ('Value'); IF @@ERROR <> 0 ROLLBACK TRANSACTION InnerTran; COMMIT TRANSACTION InnerTran; -- More actions... IF AllGood = 1 COMMIT TRANSACTION OuterTran; ELSE ROLLBACK TRANSACTION OuterTran; ``` 尽管如此,请注意并非所有的 DBMS 都完全支持标准定义下的多层次结构化的交易管理功能——比如 MySQL 默认情况下不提供严格意义上的 nested transaction 支持[^6]。 #### Oracle 的 Savepoint 方法 Oracle 提供 savepoints 作为处理复杂事务的一种手段。Savepoints 让程序员能够在长事务期间创建检查点,从而使得能够有选择性地回退到这些特定位置而不是放弃全部未保存的工作成果: ```plsql SET AUTOCOMMIT OFF; DECLARE v_error EXCEPTION; BEGIN INSERT INTO employees (...); SAVEPOINT before_bonus_update; UPDATE bonuses SET bonus=bonus*1.1 WHERE employee_id=... ; RAISE v_error; -- Simulate an error condition EXCEPTION WHEN OTHERS THEN ROLLBACK TO SAVEPOINT before_bonus_update; END; / COMMIT; ``` 以上脚本展示了如何利用 PL/SQL 编程语言结合异常处理器来构建更加健壮的应用程序逻辑流控方案[^7]。 ### 注意事项 - 不同的关系型数据库产品对于嵌套事务的支持程度存在差异,开发人员应当查阅所使用的具体产品的官方文档获取最精确的信息。 - 使用不当可能导致死锁或者资源争用等问题,因此建议谨慎设计涉及多个并发访问路径的数据操纵流程[^8]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值