【问题标题】:How can I force TransactionScope to use the same connection across Database calls?如何强制 TransactionScope 在数据库调用中使用相同的连接?
【发布时间】:2010-07-27 16:01:24
【问题描述】:

大家早上好,

我有类似下面的代码

try{
    using(var tx = new TransactionScope()){

        var Xupdated  = someDao.DoSomeUpdateQuery(); //this dao uses MS Data ApplicationBlock

        var Yupdated = someDao.DoSomeOtherUpdateQuery(); //this dao also uses MS Data ApplicationBlock

     if(Xupdated && Yupdated)
     {
        tx.Complete();
     }

    }
} catch(Exception ex){

   DoSomethingWithTheException();
}

dao 方法有这样的代码

 try{
 var db = DatabaseFactory.CreateDatabase();
 var cmd = db.GetStoredProcCommand(someSP);
  var retVal = db.ExecuteNonQuery(cmd);
 return (retVal > 0);
} catch (SqlException ex){
    CustomException custom = new CustomException(ex.Message, ex);
  throw custom;

}

这里的问题是当 'Yupdated' 返回 false 时,我希望回滚 'DoSomeUpdateQuery()'。不幸的是,“DoSomeUpdateQuery()”更改已提交。我该如何补救?我在其中设置了一个断点,并且永远不会调用 tx.Complete()。有谁知道我如何在这里获得适当的所需行为?提前感谢您的任何指点。

干杯,
~ck 在圣地亚哥

【问题讨论】:

    标签: c# sql-server transactions try-catch transactionscope


    【解决方案1】:

    只要DatabaseFactory 类(无论它是什么)以合作的方式运行,您就已经有了适当的行为。如果 someDao 调用似乎独立运行,则可能意味着它们正在使用TranscationScopeOption.Supress 积极创建内部范围。另一个问题可能是CreateDatabase 调用在内部缓存了一些 SqlConnection 并且不依赖于 SqlClient 连接池,因此可能会绕过连接注册进入事务。

    附带说明一下,即使这按预期工作,它也将非常低效,因为您会将两个不同的连接注册到分布式事务中,这将减慢处理伟大交易的速度。一个好的数据访问层接受 Sqlconnection 作为参数,这样它就可以在调用之间共享它,从而保持服务器上的事务范围本地

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多