Linq to Sql 事务处理

Linq to SQL支持三种事务处理模型:显式本地事务、显式可分发事务、隐式事务

1. 隐式事务

    当调用SubmitChanges 时,L2S会检查当前环境是否开启了事务(下面两节中创建的事务),如果没有开始事务,则 L2S启动本地事务(IDbTransaction),并使用此事务执行所生成的 SQL 命令。

    使用Reflector查看DataContext.SubmitChanges的源代码(见本文最后的附录),可以看到,如果开启了一个事务,并将其传给DataContext.Transaction,则在执行SubmitChanges时就不会再重新开启一个新的事务了。

进行此调用时,DataContext 会设法将您所做的更改转换为等效的 SQL 命令。您可以使用自己的自定义逻辑来重写这些操作,但提交顺序是由 DataContext 的一项称作“更改处理器”的服务来协调的。事件的顺序如下:

  1. 当您调用 SubmitChanges 时,LINQ to SQL 会检查已知对象的集合以确定新实例是否已附加到它们。如果已附加,这些新实例将添加到被跟踪对象的集合。

  2. 所有具有挂起更改的对象将按照它们之间的依赖关系排序成一个对象序列。如果一个对象的更改依赖于其他对象,则这个对象将排在其依赖项之后。

  3. 在即将传输任何实际更改时,LINQ to SQL 会启动一个事务来封装由各条命令组成的系列。

  4. 对对象的更改会逐个转换为 SQL 命令,然后发送到服务器。

    此时,如果数据库检测到任何错误,都会造成提交进程停止并引发异常。将回滚对数据库的所有更改,就像未进行过提交一样。DataContext 仍具有所有更改的完整记录。

先执行Insert,再执行Update;执行Update时出现了SqlException异常。这时查看测试表TLINQ中的数据,发现没有插入新的记录进去。也就是说,这里使用了事务,但是SQL Server Profile没有跟踪到
    下面一节中即使执行DbConnection.BeginTransaction(),也不会跟踪到begin tran和commit tran。

    最后总结一下隐式事务的优缺点:

    优点:使用简单,L2S都帮我们搞定了,我们不需要写任何代码。

    缺点:只能处理单个DataContext中的单个SubmitChanges()函数的调用。如果需要将SubmitChanges()与其他自定义更新操作(譬如ExcuteCommand)共用一个Transaction、或者与其他DataContext共用一个DBTransation

 

2. 显式本地事务

    SubmitChanges只能处理最基本的CUD(Create/Update/Delete)操作;而在日常的应用中,逻辑往往没有这么简单,或者考虑性能等因素,我们需要配合ADO.Net执行原生的TSQL;这时我们可能要让ADO.Net + Linq to SQL来进行配合处理。

    也就是说,我们可以手工创建一个DbConnection和DbTransaction,然后传给DataContext

  优点:可以配合Ado.Net一起使用,或者跨DataContext使用,实现负责的业务逻辑。

    缺点:处理步骤比较繁琐。L2S中的DataContext已经提供了ExcuteCommand方法来执行原生的TSQL

3. 显式可分发事务

    使用TransactionScope来进行显示可分发事务控制。于是这个操作就有了事务功能。关于TransactionScope的详细介绍,可以参考MSDN:使用事务范围实现隐式事务,及SQL Server的联机丛书:CLR 集成和事务

简洁,把要执行的操作封装在一个或多个Action中,然后传递给TransactioExtension.Excute即可。对于封装在TransactionScope里面执行的所有操作(譬如SubmitChanges,ExcuteCommand、ExecuteQuery),最终都会解析为对ADO.NET的调用;而ADO.Net会在调用 Connection.Open 方法时自动检查Transaction.Current,并在该事务中以透明方式登记连接(除非在连接字符串中将 Enlist 关键字设置为 false)。

    SqlConnection 对象的 ConnectionString 属性支持 Enlist 关键字,该关键字指示 System.Data.SqlClient 是否检测事务上下文并在分布式事务中自动登记连接。如果此关键字设置为 True(默认设置),则会在打开的线程的当前事务上下文中自动登记连接。如果此关键字设置为 False,则 SqlClient 连接不会与分布式事务交互。如果未在连接字符串中指定 Enlist,并且如果在打开相应连接时检测到一个分布式事务,则会在此分布式事务中自动登记此连接

    优点:使用简单,可以配合ADO.Net或者DataContext.ExcuteCommand使用,可以跨DataContext使用,可以跨数据库使用,可以跨服务器使用。

    缺点:分布式事务通常会使用大量的系统资源。Microsoft 分布式事务处理协调器 (MS DTC) 会管理此类事务,并集成在这些事务中访问的所有资源管理器。庆幸的是:在打开一个具有活动TransactionScope事务的连接而未打开任何其他连接的情况下,该事务会以轻型事务的形式提交,而不是产生完全分布式事务的额外开销。

 

猜你喜欢

转载自blog.csdn.net/qq_41261286/article/details/85115575
今日推荐