如何强制TransactionScope跨数据库调用使用相同的连接?

时间:2010-07-27 16:01:25

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

早安全,

我的代码类似于以下

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()永远不会被调用。有谁知道我怎么能在这里获得适当的理想行为?提前感谢任何指示。

干杯,
〜在圣地亚哥

1 个答案:

答案 0 :(得分:0)

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

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