Linq To Sql : 三种事务处理方式

17 篇文章 0 订阅
15 篇文章 0 订阅

Linq To Sql : 三种事务处理方式

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

1.隐式事务
当调用SubmitChanges 时,L2S会检查当前环境是否开启了事务(下面两节中创建的事务),如果没有开始事务,则 L2S启动本地事务(IDbTransaction),并使用此事务执行所生成的 SQL 命令。
使用Reflector查看DataContext.SubmitChanges的源代码(见本文最后的附录),可以看到,如果开启了一个事务,并将其传给DataContext.Transaction,则在执行SubmitChanges时就不会再重新开启一个新的事务了。 例如,下面的代码会创建应隐式事务:

    public static void TestTranIn2000()
   	{
       using (SQL2000.Sql2000DataContext context1 = new SQL2000.Sql2000DataContext())
       {
           List<SQL2000.TLINQ> linq = context1.TLINQ.ToList();
           linq.ForEach(e => e.Value += e.Value);
        context1.SubmitChanges();
       }
    }

可以打开SQL Server Profile来查看生成的T-SQL,生成的Update语句被包含在Begin Transaction和Commit Transaction之间,如下图所示:
在这里插入图片描述

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

    也就是说,我们可以手工创建一个DbConnection和DbTransaction,然后传给DataContext,代码示例如下:

   1: public static void TestTranInSQL2008()
   2: {
   3:     using(SqlConnection conn = new SqlConnection(Settings.Default.AdventureWorksConnectionString))
   4:     {
   5:         conn.Open(); //1. 创建并打开DbConnection连接
   6:         using (SqlTransaction tran = conn.BeginTransaction()) //2. 开启DbTransaction
   7:         {
   8:             //3. 使用ADO.Net执行TSQL
   9:             SqlCommand cmd = new SqlCommand("Update TLinq SET Value=10", conn, tran);
  10:             cmd.ExecuteNonQuery();
  11:  
  12:             //4. 配合Ado.Net和Linq to Sql: 将ADO.Net的DbConnection和DbTransaction传给Linq to Sql
  13:             using (AdventureWorksDataContext context1 = new AdventureWorksDataContext(conn))
  14:             {
  15:                 context1.Transaction = tran;
  16:                 List<TLINQ> linq = context1.TLINQ.ToList();
  17:                 context1.TLINQ.InsertOnSubmit(new TLINQ() { Value = "1" });
  18:                 linq.ForEach(e => e.Value = (Convert.ToInt32(e.Value) + 1).ToString());
  19:                 context1.SubmitChanges();
  20:             }
  21:  
  22:             tran.Commit(); //5. 需要提交手工创建的事务
  23:         }
  24:     }
  25: }
  
  1. 显式可分发事务
    使用TransactionScope来进行显示可分发事务控制。TransactionScope就像事务处理里面的一面魔镜,如果需要事务,就对着它喊:“主啊,请赐我事务!”,于是这个操作就有了事务功能。关于TransactionScope的详细介绍,可以参考MSDN:使用事务范围实现隐式事务,及SQL Server的联机丛书:CLR 集成和事务

    使用显式可分发事务进行处理的示例代码如下:

  1: public static void TestTransactionScopeInSQL2008()
   2: {
   3:     Action action = () => //1.把要执行的操作封装在一个或多个Action中
   4:     {
   5:         using (AdventureWorksDataContext context1 = new AdventureWorksDataContext())
   6:         {
   7:             context1.ExecuteCommand("Update TLinq SET Value={0}", 10);
   8:             List<TLINQ> linq = context1.TLINQ.ToList();
   9:             context1.TLINQ.InsertOnSubmit(new TLINQ() { Value = "1" });
  10:             linq.ForEach(e => e.Value = (Convert.ToInt32(e.Value) + 1).ToString());
  11:             context1.SubmitChanges();
  12:         }
  13:     };
  14:     TransactioExtension.Excute(action); 
  15: }

或者这样:

   1: /// <summary>
   2: /// 此方法里面完全不必考虑事务
   3: /// </summary>
   4: public static void TestTransactionScopeInSQL2008()
   5: {
   6:     using (AdventureWorksDataContext context1 = new AdventureWorksDataContext())
   7:     {
   8:         context1.ExecuteCommand("Update TLinq SET Value={0}", 10);
   9:         List<TLINQ> linq = context1.TLINQ.ToList();
  10:         context1.TLINQ.InsertOnSubmit(new TLINQ() { Value = "1" });
  11:         linq.ForEach(e => e.Value = (Convert.ToInt32(e.Value) + 1).ToString());
  12:         context1.SubmitChanges();
  13:     }
  14: }
  15:  
  16: //而在外面直接这样使用
  17: TransactioExtension.Excute(() => TestTransactionScopeInSQL2008());

最后来个汇总:

事务类型优点缺点
隐式事务使用简单,由L2S自动处理。仅限于单个DataContext中的SubmitChanges方法内使用。
显式本地事务可以配合Ado.Net一起使用,可以跨多个DataContext来使用使用相对繁琐一点儿;且不支持与DataContext.ExecuteCommand配合使用
显式可分发事务功能强大(可以配合ADO.Net或者DataContext.ExcuteCommand使用,可以跨DataContext使用,可以跨数据库使用,可以跨服务器使用),使用简单可能会对性能有一些影响
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星丿曲丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值