简述.NET事务应用原则

简介:

.NET事务应用原则

1.在同一个数据库内进行CRUD时,应使用同一个DbConnection对象,且显式指定DbConnection均为同一个DbTransaction,示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//在同一个DB中操作一个表时,可以不用显式指定事务,因为单条SQL命令就是一个最小的事务单元
         using  (DbConnection conn = new  SqlConnection( "数据库连接字符串" ))
         {
             var  cmd = conn.CreateCommand();
             cmd.CommandText = "delete users" ;
             cmd.ExecuteNonQuery();
         }
 
 
         //在同一个DB中操作多个表或执行不同的SQL命令时,需要显式指定事务,且需确保每个Command均与同一个DbTransaction关联
         using  (DbConnection conn = new  SqlConnection( "数据库连接字符串" ))
         {
             DbTransaction tran = conn.BeginTransaction();
             try
             {
                 var  cmd = conn.CreateCommand();
                 cmd.Transaction = tran;
                 cmd.CommandText = "delete users" ;
                 cmd.ExecuteNonQuery();
 
                 var  cmd2 = conn.CreateCommand();
                 cmd2.Transaction = tran;
                 cmd2.CommandText = "delete roles" ;
                 cmd2.ExecuteNonQuery();
 
                 tran.Commit();
             }
             catch  (Exception ex)
             {
                 Console.WriteLine(ex.Message);
                 tran.Rollback();
             }
         }

2.在同一个服务器上的不同数据库之间进行CRUD时,应使用同一个DbConnection对象,且显式指定DbConnection均为同一个DbTransaction,同时SQL命令语句中的包含的对象(表、视图、存储过程、函数等)应显式指定数据库名称,格式如:databasename.owner.tablename,如:Db1.dbo.Users;Db2.dbo.Users;(前提条件:多个数据库的用户名及密码相同的情况下,否则就只能使用分布式事务),示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//在同一个Server不同的DB中操作多个表或执行不同的SQL命令时,需要显式指定事务,且需确保每个Command均与同一个DbTransaction关联,CommandText还应显式添加数据库名称
         using  (DbConnection conn = new  SqlConnection( "数据库连接字符串" ))
         {
             DbTransaction tran = conn.BeginTransaction();
             try
             {
                 var  cmd = conn.CreateCommand();
                 cmd.Transaction = tran;
                 cmd.CommandText = "delete db1.dbo.users" ;
                 cmd.ExecuteNonQuery();
 
                 var  cmd2 = conn.CreateCommand();
                 cmd2.Transaction = tran;
                 cmd2.CommandText = "delete db2.dbo.roles" ;
                 cmd2.ExecuteNonQuery();
 
                 tran.Commit();
             }
             catch  (Exception ex)
             {
                 Console.WriteLine(ex.Message);
                 tran.Rollback();
             }
         }

3.在不同的DB服务器上进行CRUD时,应使用分布式事务,可以采取隐式或显式开启分布式事务,示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
//采用隐式开启分布式事务
         using  (TransactionScope tranScope = new  TransactionScope(TransactionScopeOption.RequiresNew))
         {
             using  (DbConnection conn = new  SqlConnection( "数据库连接字符串" ))
             {
                 conn.Open();
                 var  cmd = conn.CreateCommand();
                 cmd.CommandText = "delete users" ;
                 cmd.ExecuteNonQuery();
             }
 
 
             using  (DbConnection conn2 = new  SqlConnection( "数据库连接字符串2" ))
             {
                 conn2.Open();
                 var  cmd2 = conn2.CreateCommand();
                 cmd2.CommandText = "delete users" ;
                 cmd2.ExecuteNonQuery();
             }
             tranScope.Complete();
         }
 
         //采用显式开启分布式事务
         using  (CommittableTransaction committableTransaction = new  CommittableTransaction())
         {
             try
             {
                 using  (DbConnection conn = new  SqlConnection( "数据库连接字符串" ))
                 {
                     conn.Open();
                     conn.EnlistTransaction(committableTransaction); //将连接登记到可提交事务
                     var  cmd = conn.CreateCommand();
                     cmd.CommandText = "delete users" ;
                     cmd.ExecuteNonQuery();
                 }
 
 
                 using  (DbConnection conn2 = new  SqlConnection( "数据库连接字符串2" ))
                 {
                     conn2.Open();
                     conn2.EnlistTransaction(committableTransaction); //将连接登记到可提交事务
                     var  cmd2 = conn2.CreateCommand();
                     cmd2.CommandText = "delete users" ;
                     cmd2.ExecuteNonQuery();
                 }
 
                 committableTransaction.Commit();
             }
             catch  (Exception ex)
             {
                 committableTransaction.Rollback(ex);
             }
         }
 
         //采用显式开启分布式事务,模拟TransactionScope用法的过程
         {
             Transaction originalTransaction = Transaction.Current; //记录当前的环境事务,用于后面的恢复
             CommittableTransaction committableTransaction = null ;
             DependentTransaction dependentTransaction = null ;
             committableTransaction = new  CommittableTransaction();
             Transaction.Current = committableTransaction; //将定义的可提交事务作为当前的环境事务
 
             try
             {
 
                 using  (DbConnection conn = new  SqlConnection( "数据库连接字符串" ))
                 {
                     conn.Open();
                     var  cmd = conn.CreateCommand();
                     cmd.CommandText = "delete users" ;
                     cmd.ExecuteNonQuery();
                 }
 
                 dependentTransaction = Transaction.Current.DependentClone(DependentCloneOption.RollbackIfNotComplete); //复制当前的环境事务从而产生新的依赖事务,且指定必需等到该事务完成
                 Transaction.Current = dependentTransaction; //将复制到的新的依赖事务
 
                 using  (DbConnection conn2 = new  SqlConnection( "数据库连接字符串2" ))
                 {
                     conn2.Open();
                     var  cmd2 = conn2.CreateCommand();
                     cmd2.CommandText = "delete users" ;
                     cmd2.ExecuteNonQuery();
                 }
 
                 dependentTransaction.Complete();
                 committableTransaction.Commit();
             }
             catch  (Exception ex)
             {
                 Transaction.Current.Rollback(ex);
             }
             finally  //不论成功与否,最终都将恢复成原来的环境事务
             {
                 Transaction transaction = Transaction.Current;
                 Transaction.Current = originalTransaction;
                 transaction.Dispose();
             }
 
         }

最终总结一下:

1.查询无需事务;

2.涉汲执行增、删、改的SQL命令时,应考虑是否需要确保执行数据的一致性,若需要则必需使用事务,否则可以采取默认方式;

3.在同一个DB服务器中,尽可能的使用本地事务,跨多个DB服务器中,需要使用分布式事务;

4.尽可能的缩小事务的使用范围,避免出现多层级的嵌套事务;

5.若需要使用分布式事务,在WINDOWS下需要开启MS DTC服务(分布式事务管理器)

本文转自 梦在旅途 博客园博客,原文链接: http://www.cnblogs.com/zuowj/p/5196197.html ,如需转载请自行联系原作者

相关文章
|
存储 Shell Linux
快速上手基于 BaGet 的脚本自动化构建 .net 应用打包
本文介绍了如何使用脚本自动化构建 `.net` 应用的 `nuget` 包并推送到指定服务仓库。首先概述了 `BaGet`——一个开源、轻量级且高性能的 `NuGet` 服务器,支持多种存储后端及配置选项。接着详细描述了 `BaGet` 的安装、配置及使用方法,并提供了 `PowerShell` 和 `Bash` 脚本实例,用于自动化推送 `.nupkg` 文件。最后总结了 `BaGet` 的优势及其在实际部署中的便捷性。
516 10
|
Linux C++ Windows
【Azure 应用服务】Azure App Service(Windows)环境中如何让.NET应用调用SAP NetWeaver RFC函数
【Azure 应用服务】Azure App Service(Windows)环境中如何让.NET应用调用SAP NetWeaver RFC函数
132 0
【Azure 应用服务】Azure App Service(Windows)环境中如何让.NET应用调用SAP NetWeaver RFC函数
|
8月前
|
C# Android开发 iOS开发
2025年全面的.NET跨平台应用框架推荐
2025年全面的.NET跨平台应用框架推荐
310 23
|
10月前
|
开发框架 监控 .NET
【Azure App Service】部署在App Service上的.NET应用内存消耗不能超过2GB的情况分析
x64 dotnet runtime is not installed on the app service by default. Since we had the app service running in x64, it was proxying the request to a 32 bit dotnet process which was throwing an OutOfMemoryException with requests >100MB. It worked on the IaaS servers because we had the x64 runtime install
157 5
|
10月前
|
JSON 算法 安全
JWT Bearer 认证在 .NET Core 中的应用
【10月更文挑战第30天】JWT(JSON Web Token)是一种开放标准,用于在各方之间安全传输信息。它由头部、载荷和签名三部分组成,用于在用户和服务器之间传递声明。JWT Bearer 认证是一种基于令牌的认证方式,客户端在请求头中包含 JWT 令牌,服务器验证令牌的有效性后授权用户访问资源。在 .NET Core 中,通过安装 `Microsoft.AspNetCore.Authentication.JwtBearer` 包并配置认证服务,可以实现 JWT Bearer 认证。具体步骤包括安装 NuGet 包、配置认证服务、启用认证中间件、生成 JWT 令牌以及在控制器中使用认证信息
362 2
|
12月前
|
数据采集 JSON API
.NET 3.5 中 HttpWebRequest 的核心用法及应用
【9月更文挑战第7天】在.NET 3.5环境下,HttpWebRequest 类是处理HTTP请求的一个核心组件,它封装了HTTP协议的细节,使得开发者可以方便地发送HTTP请求并接收响应。本文将详细介绍HttpWebRequest的核心用法及其实战应用。
453 6
|
Linux iOS开发 开发者
跨平台开发不再难:.NET Core如何让你的应用在Windows、Linux、macOS上自如游走?
【8月更文挑战第28天】本文提供了一份详尽的.NET跨平台开发指南,涵盖.NET Core简介、环境配置、项目结构、代码编写、依赖管理、构建与测试、部署及容器化等多个方面,帮助开发者掌握关键技术与最佳实践,充分利用.NET Core实现高效、便捷的跨平台应用开发与部署。
1301 3
|
缓存 Java API
【揭秘】.NET高手不愿透露的秘密:如何让应用瞬间提速?
【8月更文挑战第28天】本文通过对比的方式,介绍了针对 .NET 应用性能瓶颈的优化方法。以一个存在响应延迟和并发处理不足的 Web API 项目为例,从性能分析入手,探讨了使用结构体减少内存分配、异步编程提高吞吐量、EF Core 惰性加载减少数据库访问以及垃圾回收机制优化等多个方面,帮助开发者全面提升 .NET 应用的性能和稳定性。通过具体示例,展示了如何在不同场景下选择最佳实践,以实现更高效的应用体验。
178 3
|
前端开发 JavaScript 开发工具
跨域联姻:React.NET——.NET应用与React的完美融合,解锁前后端高效协作新姿势。
【8月更文挑战第28天】探索React.NET,这是将热门前端框架React与强大的.NET后端无缝集成的创新方案。React以其组件化和虚拟DOM技术著称,能构建高性能、可维护的用户界面;.NET则擅长企业级应用开发。React.NET作为桥梁,使.NET应用轻松采用React构建前端,并优化开发流程与性能。通过直接托管React组件,.NET应用简化了部署流程,同时支持服务器端渲染(SSR),提升首屏加载速度与SEO优化。
391 1
|
存储 缓存 安全
.NET 在金融行业的应用:高并发交易系统的构建与优化之路
【8月更文挑战第28天】在金融行业,交易系统需具备高并发处理、低延迟及高稳定性和安全性。利用.NET构建此类系统时,可采用异步编程提升并发能力,优化数据库访问以降低延迟,使用缓存减少数据库访问频率,借助分布式事务确保数据一致性,并加强安全性措施。通过综合优化,满足金融行业的严苛要求。
251 1