TransactionScope不回滚查询

时间:2016-04-28 12:17:34

标签: c# sql asp.net transactionscope

我有两个必须一起工作的查询。首先是更新,其次是插入查询。我将它们放入 TransactionScope 范围:

using (TransactionScope scope = new TransactionScope())
{
    SqlCommand updateCmd = new SqlCommand("UPDATE V_Stock SET Quantity= 5 WHERE Id=" + shelfId, con);
    SqlCommand insertCmd = new SqlCommand("INSERT INTO V_Stock (Code, Quantity,   Name) VALUES (@1, @2, @3)", con);
    insertCmd.Parameters.AddWithValue("@1", "Code1");
    insertCmd.Parameters.AddWithValue("@2", 15);
    insertCmd.Parameters.AddWithValue("@3", "Name1");
    try
    {
        updateCmd.ExecuteNonQuery();
        insertCmd.ExecuteNonQuery();            
    }
    catch (Exception ex)
    {
        scope.Complete();
        string s = ex.ToString();
    }
}

更新查询正常工作,但插入查询没有。在这种情况下,我不想执行它们。只有当它们正常工作时才应该执行它们。

我可以一起处理这些查询吗?

1 个答案:

答案 0 :(得分:2)

  • 当您准备提交交易时,需要致电scope.Complete,而不是在交易失败时。{/ li>
  • 您还应该打开TransactionScope范围内的连接,以便在该范围内注册连接。
  • 此外,我不确定您的SqlConnection实例的定义位置。 Microsoft团队始终建议您使用短期连接,使用它们并删除它们。让Sql Server处理连接池(默认情况下这通常是打开的),这样可以非常便宜地使用并丢弃c#代码中的sql连接。

以下是一些重构代码,我添加了一些我在TransactionScope

的Microsoft定义中找到的文档
using (TransactionScope scope = new TransactionScope())
{
    using (SqlConnection con = new SqlConnection(yourConnectString))
    {
        // according to the documentation on TransactionScope
        // Opening the connection automatically enlists it in the 
        // TransactionScope as a lightweight transaction.
        con.Open();

        // I changed this to make it parameterized as well although this had nothing to do with the TransactionScope question
        SqlCommand updateCmd = new SqlCommand("UPDATE V_Stock SET Quantity= 5 WHERE Id= @shelfId", con);
        updateCmd.Parameters.AddWithValue("@shelfId", shelfId);

        SqlCommand insertCmd = new SqlCommand("INSERT INTO V_Stock (Code, Quantity, Name) VALUES (@1, @2, @3)", con);
        insertCmd.Parameters.AddWithValue("@1", "Code1");
        insertCmd.Parameters.AddWithValue("@2", 15);
        insertCmd.Parameters.AddWithValue("@3", "Name1");

        updateCmd.ExecuteNonQuery();
        insertCmd.ExecuteNonQuery();            

        // according to the documentation on TransactionScope
        // The Complete method commits the transaction. If an exception has been thrown,
        // Complete is not  called and the transaction is rolled back.
        scope.Complete();
    }
}