当前位置:主页   - 电脑 - 网站开发 - ASP.Net
Linq to SQL之使用事务
来源:网络   作者:   更新时间:2012-08-03
收藏此页】    【字号    】    【打印】    【关闭

  事务是一个原子的工作单位,必须完整的完成单位里的所有工作,要么全部执行,要么全部都不执行。如果提交事务,则事务执行成功;如果回滚事务,则事务执行失败。 事务具备4个基本特性--ACID(原子性、一致性、孤立性和持久性)。

   在Linq to SQL中,有三种方法创建事务:

  如果没有指定任何事务,那么当调用SubmitChanges方法时,DataContext会默认创建一个事务。

  使用TransactionScope创建轻量级事务

  给DataContext的Transaction属性指定事务 

  下面我用代码分别来说明这几种创建事务的方法,以Northwind数据库为例,先来看看直接使用SubmitChanges:

 NorthwindDataContext ctx = new NorthwindDataContext();

 Customer c1 = new Customer { CustomerID = "TESTA", CompanyName = "testa's company" };
 Customer c2 = new Customer { CustomerID = "TESTBC", CompanyName = "testb's company" };

 ctx.Customers.Add(c1);
 ctx.Customers.Add(c2);

 ctx.SubmitChanges();

  上面这段代码中,先创建了两个Customer对象然后添加到DataContext里面,其中的c2的CustomerID赋值为"TESTBC",长度为六个字符,而数据库中该字段约束为5个字符长度,这样在SubmitChanges的时候应该会有异常抛出。果然在执行的时候抛出了SqlException,提示字符将被截断。

Linq to SQL之使用事务

  再通过Sql Server管理器可以看到上面这两条数据都没有被插入到数据库中。通过Reflector可以发现在SubmitChanges的时候,Linq to SQL默认创建了一个孤立级别为Read Committed的事务(它表示已提交的更新在事务间是可见的,具体有哪些孤立级别可以参考ADO.NET相关资料):

 public virtual void SubmitChanges(ConflictMode failureMode)
 {
   ...
   transaction = this.provider.Connection.BeginTransaction(IsolationLevel.ReadCommitted);
   this.provider.Transaction = transaction;

 }

如果不想使用默认的事务设置,比如想改变事务的孤立级别,我们可以给DataContext的Transaction属性赋值,以此使用自定义的事务。

 ctx.Transaction = ctx.Connection.BeginTransaction(System.Data.IsolationLevel.Serializable);
 try
 {
   ctx.SubmitChanges();
   ctx.Transaction.Commit();
 }
 catch
 {
   ctx.Transaction.Rollback();
   throw;
 }
 finally
 {
   ctx.Transaction = null;
 }

  最后一种方式是通过TransactionScope创建轻量级事务,就像在ADO.NET中使用一样:

 using (TransactionScope scope = new TransactionScope())
 {
   ctx.SubmitChanges();
   scope.Complete();

 }

  上面的例子看起来似乎多此一举,因为在SubmitChanges中会创建默认的事务,但是改成下面这样,就只能使用自定义的事务了:

 using (TransactionScope scope = new TransactionScope())
 {
   ctx.ExecuteCommand("exec ....");
   ctx.ExecuteCommand("exec ....");
   ctx.ExecuteCommand("exec ....");
   ctx.SubmitChanges();
   scope.Complete();

 }

  不管ExecuteCommand里面执行了哪些操作,我们都能够指明这些行为和SubmitChanges处于同一个事务中。

其它资源
来源声明

版权与免责声明
1、本站所发布的文章仅供技术交流参考,本站不主张将其做为决策的依据,浏览者可自愿选择采信与否,本站不对因采信这些信息所产生的任何问题负责。
2、本站部分文章来源于网络,其版权为原权利人所有。由于来源之故,有的文章未能获得作者姓名,署“未知”或“佚名”。对于这些文章,有知悉作者姓名的请告知本站,以便及时署名。如果作者要求删除,我们将予以删除。除此之外本站不再承担其它责任。
3、本站部分文章来源于本站原创,本站拥有所有权利。
4、如对本站发布的信息有异议,请联系我们,经本站确认后,将在三个工作日内做出修改或删除处理。
请参阅权责声明