C# TransactionScope

TransactionScope

TransactionScope事务处理经常用到,老是用了又忘,做点记录。
TransactionScope的定义使用介绍


TransactionScopeOption

TransactionScopeOption枚举型用来决定一个TransactionScope是用已有的事务,还是定义TransactionScope的新做一个事务,还是完全不用事务。默认是Required,Required表示如果已有事务,就加入该事务,否则新建一个事务。

TransactionOptions

TransactionOptions 结构体用来设置TransactionScope所用到事务的隔离级别超时时间
隔离级别参考这篇博文。(乐观锁


实践

做两张表

USE [Learning]
GO
CREATE TABLE [dbo].[Foo](
	[Id] [bigint] IDENTITY(1,1) NOT NULL,
	[Value] [nvarchar](50) NULL,
 CONSTRAINT [PK_Foo] PRIMARY KEY CLUSTERED 
(
	[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO

CREATE TABLE [dbo].[Bar](
	[Id] [bigint] IDENTITY(1,1) NOT NULL,
	[Value] [nvarchar](50) NULL,
 CONSTRAINT [PK_Bar] PRIMARY KEY CLUSTERED 
(
	[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY
<think>我们正在讨论C#中的TransactionScope类。根据引用[1]和[2],TransactionScope是一个用于简化事务管理的类,它可以确保一系列操作要么全部成功提交,要么全部回滚,从而保持数据的一致性。它支持分布式事务和本地事务。 根据引用[3],TransactionScope使用TransactionScopeOption枚举来决定事务行为,默认值为Required,表示如果已有事务则加入,否则新建一个事务。此外,还可以通过TransactionOptions设置事务的超时和隔离级别。 现在,我们将详细解释TransactionScope的使用方法,包括创建事务范围、事务选项、嵌套事务以及异常处理等。 ### TransactionScope基本使用 使用TransactionScope的基本步骤如下: 1. 创建`TransactionScope`对象。 2. 在`using`块内执行数据库操作(如多个数据库操作)。 3. 如果所有操作成功,调用`Complete()`方法提交事务。 4. 如果出现异常,事务将自动回滚。 示例代码: ```csharp using (TransactionScope scope = new TransactionScope()) { try { // 执行数据库操作1 // 执行数据库操作2 // 如果所有操作成功,则标记事务为完成 scope.Complete(); } catch (Exception ex) { // 事务会自动回滚(因为未调用Complete) // 处理异常 } } ``` ### 事务选项 在创建`TransactionScope`时,可以传入`TransactionOptions`来设置事务的超时时间和隔离级别。例如: ```csharp TransactionOptions options = new TransactionOptions(); options.IsolationLevel = IsolationLevel.ReadCommitted; // 设置隔离级别 options.Timeout = TimeSpan.FromSeconds(30); // 设置超时时间 using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, options)) { // ... 操作 scope.Complete(); } ``` ### 嵌套事务 `TransactionScope`支持嵌套事务。嵌套事务的行为由`TransactionScopeOption`控制: - `Required`:如果外部有事务,则加入外部事务;否则创建新事务。这是默认值。 - `RequiresNew`:无论外部是否有事务,都创建新事务。 - `Suppress`:不参与事务,即使外部有事务。 示例: ```csharp using (TransactionScope outerScope = new TransactionScope()) { // 外部事务 using (TransactionScope innerScope = new TransactionScope(TransactionScopeOption.RequiresNew)) { // 内部事务(独立于外部事务) innerScope.Complete(); } outerScope.Complete(); } ``` ### 分布式事务 当`TransactionScope`涉及多个不同的资源管理器(如两个不同的数据库)时,事务将自动升级为分布式事务(由MSDTC协调)。这要求MSDTC服务在相关服务器上运行。 ### 注意事项 1. 在事务范围内,应避免长时间持有资源(如数据库连接),因为事务会锁定资源。 2. 分布式事务(MSDTC)可能带来性能开销,且需要配置网络权限。 3. 确保在操作成功后调用`Complete()`方法,且只调用一次。调用`Complete()`后,不能再进行任何操作。 ### 与依赖注入框架集成 根据引用[4],在使用依赖注入框架(如Autofac)时,需要注意`TransactionScope`的生命周期。通常,`TransactionScope`的生命周期应限定在某个作用域内(如一个HTTP请求)。例如,在Autofac中,可以使用`InstancePerLifetimeScope`来确保每个作用域内只有一个`TransactionScope`实例。 ### 异步支持 从.NET Framework 4.5.1开始,`TransactionScope`支持异步操作。在异步方法中,可以使用`TransactionScopeAsyncFlowOption.Enabled`来启用异步流支持: ```csharp using (TransactionScope scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) { // 异步操作 await SomeAsyncMethod(); scope.Complete(); } ``` ### 异常处理 在事务范围内,如果发生异常,事务将回滚。如果异常被捕获,但未调用`Complete()`,事务也会回滚。因此,通常不需要在`catch`块中显式回滚。 ### 总结 `TransactionScope`提供了一种声明式的事务管理方式,简化了事务编程。通过合理设置事务选项和注意嵌套行为,可以灵活控制事务边界。同时,注意分布式事务的配置和性能影响。 §§相关问题§§ 1. TransactionScope在分布式事务中是如何工作的? 2. 如何配置MSDTC以支持分布式事务? 3. 在ASP.NET Core中如何使用TransactionScope? 4. TransactionScope和数据库事务(如SqlTransaction)有什么区别? 5. 如何避免TransactionScope导致的死锁问题?</think>### C# TransactionScope 使用详解 `TransactionScope` 是 .NET 中简化事务管理的核心类,它提供**隐式事务管理**,确保代码块内所有操作要么全部成功提交,要么全部回滚。以下是详细使用指南: #### 一、基础用法 ```csharp using (var scope = new TransactionScope()) { // 1. 数据库操作1 (如EF Core SaveChanges) dbContext.Orders.Add(order); await dbContext.SaveChangesAsync(); // 2. 数据库操作2 dbContext.Inventory.Update(stock); await dbContext.SaveChangesAsync(); // 3. 显式提交事务(必须调用!) scope.Complete(); // 提交事务 } // 未调用Complete()时自动回滚 ``` **关键点**: 1. `using` 代码块定义事务边界 2. **必须调用** `scope.Complete()` 提交事务 3. 未调用 `Complete()` 或发生异常时自动回滚 #### 二、核心配置选项 ```csharp var options = new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted, // 隔离级别 Timeout = TimeSpan.FromSeconds(30) // 超时时间 }; using (var scope = new TransactionScope( TransactionScopeOption.Required, options, TransactionScopeAsyncFlowOption.Enabled) // 启用异步支持 { // 异步操作 await ProcessAsync(); scope.Complete(); } ``` **TransactionScopeOption 详解**: - `Required`(默认):加入现有事务或创建新事务 - `RequiresNew`:始终创建新事务 - `Suppress`:不参与事务(慎用) #### 三、嵌套事务控制 ```csharp using (var outerScope = new TransactionScope()) { // 父事务 using (var innerScope = new TransactionScope( TransactionScopeOption.Required, new TransactionOptions { Timeout = TimeSpan.FromMinutes(1) } )) { // 子事务(继承父事务设置) innerScope.Complete(); } outerScope.Complete(); } ``` 嵌套规则: - 所有嵌套块必须调用 `Complete()` 父事务才会提交 - 子事务超时设置覆盖父事务 #### 四、分布式事务处理 当涉及多个资源管理器(如SQL Server + Oracle)时,自动升级为**MSDTC分布式事务**: ```csharp using (var scope = new TransactionScope()) { sqlServerDb.ExecuteCommand("UPDATE A..."); oracleDb.ExecuteCommand("UPDATE B..."); scope.Complete(); // 触发两阶段提交(2PC) } ``` **必要条件**: 1. 启用 MSDTC 服务(Windows 服务) 2. 配置防火墙允许 MSDTC 通信 #### 五、异步操作支持 .NET 4.5.1+ 需显式启用异步流: ```csharp using (var scope = new TransactionScope( TransactionScopeAsyncFlowOption.Enabled)) { await Task.Run(() => { /* 异步操作 */ }); scope.Complete(); } ``` #### 六、最佳实践 1. **事务范围最小化**:避免长时间持有事务锁 2. **超时设置**:生产环境建议 10-30 秒 3. **异常处理**: ```csharp try { using (var scope = new TransactionScope(...)) { ... } } catch (TransactionAbortedException ex) { // 处理回滚 } catch (TransactionInDoubtException ex) { // 处理不确定状态 } ``` 4. **依赖注入集成**(如 Autofac): ```csharp builder.RegisterType<TransactionScope>() .InstancePerLifetimeScope(); // 作用域生命周期[^4] ``` #### 七、典型应用场景 1. 跨数据库的原子操作(SQL Server + MySQL) 2. 消息队列与数据库一致性(如:数据库保存 + RabbitMQ 发送) 3. 文件操作与数据库更新事务 4. 微服务架构中的 Saga 模式实现基础 > ⚠️ **注意**:在云原生环境(如 Docker/Kubernetes)中,需额外配置 MSDTC 网络策略[^2]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值