事务嵌套

本文探讨了分布式事务的基础概念及实现方式,介绍了如何通过System.Transactions.TransactionScope进行事务管理,并讨论了MSDTC服务的作用及其可能带来的稳定性问题。同时,文中强调了在实际应用中合理选择事务类型的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

分布式事务,需要添加引用System.Transactions,同时启用MSDTC分布式事务服务:通常使用方式为:

 using (System.Transactions.TransactionScope ts = new System.Transactions.TransactionScope())
 {
                //代码块A
                //代码块B
                ts.Complete();//提交事务
 }

  

分布式事务本质上是引入了第三方裁判,来想办法对多个本地事务监控同时成功或同时失败,这里分享几个知识点:

A:如果代码块里,若存在两个或以上数据库链接DbConnection,则需要启动微软的MSDTC分布式事务服务。

用命令行启动或停止服务:

 

B:如果代码块里,只有一个数据库链接DbConnection,那么实际上只是本地事务在处理,就算MSDTC分布式事务服务没启动,也不会报错。

C:对于TransactionScope包含的代码块,本质是监控了代码块里数据库链接DbConnection的个数,如果有多个不同的对象,则引入MSDTC当裁判,而实际执行的事务的还是各个本地事务。

D:MSDTC总是不够稳定,我在测试时两个简单的事务一起时,按住F5不停刷新,竟然能把MSSQL服务也给挂了,而用本地事务就算跨库也不会有问题。

 

所以,不是必须的情况,尽量不要引入分布式事务,应该避免使用TransactionScope来包含事务块的冲动。 

 

二、

现在知道了TransactionScope中的数据库操作实际是参与了其中的环境事务,将它理解为是自动建立的SqlTransaction,而嵌套在其中的TransactionScope中的数据库操作会添加到这个环境事务中(以TransactionScopeOption.Required为参数生成的TransactionScope)。

  也知道了Complete方法并不是执行后,就会提交事务,而只是表明之前的动作都符合要求,只是一种确认,不执行该方法,事务便不能完成。而只有最外层TransactionScope执行了Complete方法后,在离开using块时,事务才真正的提交。所以说TransactionScope是能嵌套的。

  Transaction类有一静态属性Current,在一个TransactionScope中的Complete方法执行之前可以访问,它返回的便是环境事务。

但是:   进入和退出事务都要快,这一点非常重要,因为事务会锁定宝贵的资源。最佳实践要求我们在需要使用事务之前再去创建它,在需要对其执行命令前迅速打开连接,执行动作查询 (Action Query),并尽可能快地完成和释放事务。在事务执行期间,您还应该避免执行任何不必要的、与数据库无关的代码,这能够防止资源被毫无疑义地锁定过长的时间

转载于:https://www.cnblogs.com/yexiaoyanzi/p/6757707.html

### 事务嵌套的使用方法与行为 数据库中的 **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]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值