如何在项目中应用Lin“.NET研究”qToSql数据库事务

简介:   本文主要涉及LinqToSql数据库事务相关,文章不足之处,欢迎您指出。  一、回顾T-SQL中的事务机制  代码如下: 1 /*加入事务机制后的存储过程*/ 2  create procedure sp_example 3 @param1 int = null, 4 @par...

  本文主要涉及LinqToSql数据库事务相关,文章不足之处,欢迎您指出。

  一、回顾T-SQL中的事务机制

  代码如下:

 
 
1 /* 加入事务机制后的存储过程 */
2   create procedure sp_example
3 @param1 int = null ,
4 @param2 nvarchar ( 20 ) = null
5   as
6 begin tran tranName /* sql 事务的加入 */
7 insert into table0 (col1,col2,col3) values ( ' value1 ' , ' value2 ' , ' value3 ' )
8 update table1 set column1 = @param1 where 1 = 1
9 -- 删除table2中一条已经被其他外键表引用的记录,此时会报sql引用错误
10   delete from table2 where column3 = @param1
11 insert into table3 (col1,col2) values ( ' value1 ' , ' value2 ' )
12 if ( @@error = 0 )
13 commit tran tranName
14 else
15 rollback tran tranName
16   go

  以上代码是一个具备事务机制的简单存储过程,需要指出的是当上述代码执行到第十行时,此时如果该存储过程未加入事务机制那么势必会导致第10行之前已经被影响的数据库记录也不会被还原(rollback)。这样的代码是我们不想见到的,所以事务在复杂的商业逻辑中保持数据的完整性还是尤为重要的。

  二、LinqToSql 中的SubmitChanges内置事务机制

  众所周知LinqToSql 中我们的事务机制代码变的相对简单了,如以下代码:

 
 
1 public bool DeleteDepartment( int departmentId)
2 {
3 try
4 {
5 DataContext.SystemUser.DeleteOnSubmit(
6 DataContext.SystemUser.FirstOrDefault(u => u.DepartmentID == departmentId));
7
8 DataContext.Department.DeleteOnSubmit(
9 DataContext.Department.FirstOrDefault(f => f.DepartmentID == departmentId));
10
11 // 事务机制被封装到SubmitChanges方法内
12   DataContext.SubmitChanges();
13
14 return true ;
15 }
16 catch
17 {
18 return false ;
19 }
20 }

  上述代码很容易理解,在LinqToSql 为了删除一条部门记录。我们首选要删除该部门被引用的外键表记录这里是员工表,(以上代码只是为举例用,实际开发中是不会有此种业务的)当外键记录都删除成功后代码执行到第8行,这时才能能删除部门对象。否则报SqlException外键引用无法删除部门记录。我们唯一需要做的只是将 DataContext.SubmitChanges();这句放在所有Linq操作数据库语句之后这样就可以调用数据库事务机制了。比如当第5行代码执行时SystemUser还被Order表引用。当SubmitChanges执行时会自动调用transaction.Rollback()方法回滚SubmitChanges()之前的所有被影响的数据库记录,详情请阅Reflector。

  三、在LinqToSql中SubmitChange内置事务机制无法满足的业务场景

  当程序需要处理更多更复杂的商业逻辑时,我发现光凭SubmitChange方法自带的事务机制是远远不能满足的。

  该场景描述如下:

  如果为完成某一个特定的业务,需要在程序中使用多次的SubmitChanges方法。比如我们要做一个库存相关业务,该业务是由两张表组成:主表+从表。分别为主表:Depot和从表:DepotDetail 两张表。两张表关系如下:

  当我们通过LinqToSql生成一个库存对象时其实应先生成Depot对象后再将生成Depot对象的DepotID(主键)传递到DepotDetail对象中用于生成库存明细表记录。也就说为了生成库存明细表记录我们必须先生成Depot主表,那样就不得不先调用SubmitChanges方法,当保存DepotDetail对象时还需要再一次调用SubmitChanges()方法。因为调用了多次SubmitChanges方法所以SubmitChanges内置的回滚机制已经不能满足需要了。

  四、TransactionScope的应用

   我们需要引用.net 的System.Transactions 类库使用TransactionScope类,帮我们更有效的处理数据库事务机制。对TransactionScope进行封装,代码如下:

  本段代码原作者,被我稍稍改造如下: 

 
 
1 public static class DBTransactionExtension
2 {
3 public static bool Excute( out string errorMsg, params Action[] actions)
4 {
5 // 使用ReadCommitted隔离级别,保持与Sql Server的默认隔离级别一致
6 return Excute( out errorMsg, IsolationLevel.ReadCommitted, null , actions);
7
8 }
9
10 public static void Excute( out string errorMsg, IsolationLevel level, params Action[] actions)
11 {
12 Excute( out errorMsg, level, null , actions);
13 }
上海闵行企业网站设计与制作pan>14
15 public static void Excute(out string errorMsg, int timeOut, params Action[] actions)
16 {
17 Excute(out errorMsg, IsolationLevel.ReadCommitted, timeOut, actions);
18 }
19
20 public static bool Excute(out string errorMsg, IsolationLevel level, int? timeOut, params Action[] actions)
21 {
22 errorMsg = "";
23 if (actions == null || actions.Length == 0)
24 return false;
25 TransactionOptions options = new TransactionOptions();
26
27 options.IsolationLevel = level; //默认为Serializable,这里根据参数来进行调整
28
29 if (timeOut.HasValue)
30
31 options.Timeout = new TimeSpan(0, 0, timeOut.Value); //默认60秒
32
33 using (TransactionScope tran = n上海网站建设ew TransactionScope(TransactionScopeOption.Required, options))
34 {
35 try
36 {
37 Array.ForEach<Action>(actions, action => action());
38 tran.Complete(); //通知事务管理器它可以提交事务
39 return true;
40 }
41 catch (Exception ex)//回滚事务
42 {
43 errorMsg = ex.Message;
44 return false;
45 }
46 }
47 }
48
49 }

  调用DBTransactionExtension代码如下:

 
 
1 private void SaveDepot(Depot depot)
2 {
3 DataContext.Depots.InsertOnSubmit(depot);
4
5 if ( false ) // TODO:保存库存主表前的逻辑判断,条件不满足时候调用 throw new exception执行TransactionScope回滚。
6   throw new Exception( "自定义错误提示内容,最终由事务获取错误信息后抛给UI" );
7
8 // 条件满足则调用SubmitChanges
9   DataContext.SubmitChanges();
10 DepotDetail depotDetail = new DepotDetail();
11 depotDetail.DepotID = depot.DepotID;
12 depotDetail.Count = 上海徐汇企业网站设计与制作/span>100;
13
14 DataContext.DepotDetails.InsertOnSubmit(depotDetail);
15 //又调用了一次SubmitChanges
16   DataContext.SubmitChanges();
17 }
18 public Depot InvokeTransaction(Depot depot, out string errorMsg)
19 {
20 try
21 {
上海闵行企业网站制作span style="color: #008080;">22
DBTransactionExtension.Excute( out errorMsg, () => SaveDepot(depot));
23 return depot;
24 }
25 catch (Exception ex)
26 {
27 errorMsg = ex.Message;
28 return null ;
29 }
30 }

  根据上述调用方法,我们已经可以在LinqToSql中灵活的使用数据库事务了。

  五、TransactionScope类使用的注意事项

  使用TransactionScope时如果调用多次LinqToSql的DataContext对象实例(等同调用多个数据库连接),那么我们必须开启MSDTC否则事务不能正常工作,具体请阅MSDTC开启。注:TransactionScope 适用于多种 Data Provider 比如 oracle 、OleDB、ODBC等。

  最后希望本篇文章能给您带来帮助。

目录
相关文章
|
2月前
|
存储 关系型数据库 数据库
附部署代码|云数据库RDS 全托管 Supabase服务:小白轻松搞定开发AI应用
本文通过一个 Agentic RAG 应用的完整构建流程,展示了如何借助 RDS Supabase 快速搭建具备知识处理与智能决策能力的 AI 应用,展示从数据准备到应用部署的全流程,相较于传统开发模式效率大幅提升。
附部署代码|云数据库RDS 全托管 Supabase服务:小白轻松搞定开发AI应用
|
3月前
|
安全 druid Nacos
0 代码改造实现应用运行时数据库密码无损轮转
本文探讨了敏感数据的安全风险及降低账密泄漏风险的策略。国家颁布的《网络安全二级等保2.0标准》强调了企业数据安全的重要性。文章介绍了Nacos作为配置中心在提升数据库访问安全性方面的应用,并结合阿里云KMS、Druid连接池和Spring Cloud Alibaba社区推出的数据源动态轮转方案。该方案实现了加密配置统一托管、帐密全托管、双层权限管控等功能,将帐密切换时间从数小时优化到一秒,显著提升了安全性和效率。未来,MSE Nacos和KMS将扩展至更多组件如NoSQL、MQ等,提供一站式安全服务,助力AI时代的应用安全。
241 14
|
2月前
|
安全 Java Nacos
0代码改动实现Spring应用数据库帐密自动轮转
Nacos作为国内被广泛使用的配置中心,已经成为应用侧的基础设施产品,近年来安全问题被更多关注,这是中国国内软件行业逐渐迈向成熟的标志,也是必经之路,Nacos提供配置加密存储-运行时轮转的核心安全能力,将在应用安全领域承担更多职责。
|
1月前
|
存储 人工智能 数据库
视图是什么?为什么要用视图呢?数据库视图:定义、特点与应用
本文三桥君深入探讨数据库视图的概念与应用,从定义特点到实际价值全面解析。视图作为虚拟表具备动态更新、简化查询、数据安全等优势,能实现多角度数据展示并保持数据库重构的灵活性。产品专家三桥君还分析了视图与基表关系、创建维护要点及性能影响,强调视图是提升数据库管理效率的重要工具。三桥君通过系统讲解,帮助读者掌握这一常被忽视却功能强大的数据库特性。
297 0
|
3月前
|
中间件 关系型数据库 Go
Go语言数据库编程:数据迁移与事务控制
本文介绍了《Go语言实战指南》中关于数据库编程的核心内容,涵盖使用 GORM 进行数据迁移与事务控制。主要内容包括:AutoMigrate 方法自动创建或更新表结构;事务控制的自动与手动实现方式;事务隔离级别的设置;以及在 Gin 框架中统一管理事务的实践建议。适合开发阶段的数据库结构管理和事务性操作需求。
|
3月前
|
SQL 数据库
软考软件评测师——数据库系统应用
本文介绍了关系数据库的基础知识与应用,涵盖候选码定义、自然连接特点、实体间关系(如1:n和m:n)、属性分类(复合、多值与派生属性)以及数据库设计规范。同时详细解析了E-R图转换原则、范式应用(如4NF)及Armstrong公理体系。通过历年真题分析,结合具体场景(如银行信用卡额度、教学管理等),深入探讨了候选键求解、视图操作规范及SQL语句编写技巧。内容旨在帮助读者全面掌握关系数据库理论与实践技能。
|
6月前
|
SQL 数据库 索引
【YashanDB数据库】大事务回滚导致其他操作无法执行,报错YAS-02016 no free undo blocks
大事务回滚导致其他操作无法执行,报错YAS-02016 no free undo blocks
|
9月前
|
监控 前端开发 API
一款基于 .NET MVC 框架开发、功能全面的MES系统
一款基于 .NET MVC 框架开发、功能全面的MES系统
208 5
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
189 7

热门文章

最新文章