【问题标题】:Open new database connection in scope of TransactionScope without enlisting in the transaction在 TransactionScope 范围内打开新的数据库连接,而不在事务中登记
【发布时间】:2013-08-10 10:27:55
【问题描述】:

是否可以在 TransactionScope 中打开一个新的 SqlConnection,而不引用事务中的其他连接?在事务内部,我需要运行另一个不应参与事务的命令。

void test() {
    using (var t = new TransactionScope())
    using (var c = new SqlConnection(constring))
    {
        c.Open();
        try 
        {
             using (var s = new SqlCommand("Update table SET column1 = 1");
             {
                   s.ExecuteScalar();  // If this fails
             }
             t.Complete();
        }
        catch (Exception ex)
        {
             SaveErrorToDB(ex);  // I don't want to run this in the same transaction
        }
    }
}

// I don't want this to get involved in the transaction, because it would generate
// a Distributed transaction, which I don't want. I Just want the error to go to the
// db not caring about it is run inside the TransactionScope of the previous function.
void SaveErrorToDB(Exception ex) {
    using (var db = new SqlConnection(constring)) {
          db.Open();

          using (var cmd = new SqlCommand("INSERT INTO ErrorLog (msg) VALUES (" + ex.Message + "))
          {
                cmd.ExecuteNonQuery();
          }
    }

}

【问题讨论】:

    标签: c# transactionscope


    【解决方案1】:

    终于自己找到了:

    另一个SqlConnection必须用“Enlist=false”初始化,那么这个连接就不会在同一个事务中登记:

    using (var db = new SqlConnection(constring + ";Enlist=false")) {
    ...
    

    【讨论】:

    • 您还应该能够将 SaveErrorToDB 正文包装在 using (var t = new TransactionScope(TransactionScopeOptions.Suppress)) { }
    【解决方案2】:

    或者您的SaveErrorToDB 方法可以建立连接:

    void test() {
        using (var t = new TransactionScope())
        using (var c = new SqlConnection(constring))
        {
            c.Open();
            try 
            {
                 using (var s = new SqlCommand("Update table SET column1 = 1");
                 {
                       s.ExecuteScalar();  // If this fails
                 }
                 t.Complete();
            }
            catch (Exception ex)
            {
                 SaveErrorToDB(ex, c);  // I don't want to run this in the same transaction
            }
        }
    }
    
    void SaveErrorToDB(Exception ex, SqlConnection c) {
          using (var cmd = new SqlCommand("INSERT INTO ErrorLog (msg) VALUES (" + ex.Message + ", c))
          {
                cmd.ExecuteNonQuery();
          }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-12-28
      • 1970-01-01
      • 1970-01-01
      • 2011-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-30
      • 1970-01-01
      相关资源
      最近更新 更多