1

我有一些困惑,我想清除它 - 我正在使用 ADO.NET 将值插入数据库。假设我想插入 10 项,如果我在插入第 5 项的数据时遇到错误,它应该回滚我插入到数据库中的任何内容。

我刚刚阅读了事务和回滚方法的概念,也尝试在程序中实现它,但它仍然插入 4 项并给我第 5 项的错误消息。它不会回滚插入查询。

事务和回滚方法是否解决了我的问题或者我需要使用其他替代方法。

这是我的代码,

for (int i = 0; i < itemLength - 1; i++)
            {
                //--- Start local transaction ---
                myTrans = Class1.conn.BeginTransaction();

                //--- Assign transaction object and connection to command object for a pending local transaction ---
                _insertQry = Class1.conn.CreateCommand();
                _insertQry.Connection = Class1.conn;
                _insertQry.Transaction = myTrans;

                _insertQry.CommandText = "INSERT INTO Product_PropertyValue(ItemNo, PropertyNo, ValueNo) VALUES (@ItemNo, @PropertyNo, @ValueNo)";

                //_insertQry = new SqlCommand("INSERT INTO Product_PropertyValue(ItemNo, PropertyNo, ValueNo) VALUES (@ItemNo, @PropertyNo, @ValueNo)", Class1.conn);

                _insertQry.Parameters.AddWithValue("@ItemNo", _itemNo[i]);
                _insertQry.Parameters.AddWithValue("@PropertyNo", _propNo);
                _insertQry.Parameters.AddWithValue("@ValueNo", _propValue);

                _insertQry.ExecuteNonQuery();
                myTrans.Commit();
            }

谁能帮我?

4

3 回答 3

2

听起来您正在尝试实现原子提交。它要么完全插入,要么根本不插入。

尝试以下内容

SqlTransaction objTrans = null;
        using (SqlConnection objConn = new SqlConnection(strConnString))
        {
            objConn.Open();
            objTrans = objConn.BeginTransaction();
            SqlCommand objCmd1 = new SqlCommand("insert into tbExample values(1)", objConn);
            SqlCommand objCmd2 = new SqlCommand("insert into tbExample values(2)", objConn);
            try
            {
                objCmd1.ExecuteNonQuery();
                objCmd2.ExecuteNonQuery();
                objTrans.Commit();
            }
            catch (Exception)
            {
                objTrans.Rollback();
            }
            finally
            {
                objConn.Close();
            }

也看看 http://www.codeproject.com/Articles/10223/Using-Transactions-in-ADO-NET

于 2012-04-13T19:38:41.890 回答
1

我对你的代码做了 2 处修改

1)将 BeginTransaction() 移到 for 循环之外,以便所有 10 个 INSERt 语句都在一个事务中,如果您希望它们是原子的,这就是您想要的

2) 添加了一个 TRY/CATCH 块,以便在出现错误时可以回滚。

        //--- Start local transaction ---
        myTrans = Class1.conn.BeginTransaction();
        bool success = true;

        try
        {
            for (int i = 0; i < itemLength - 1; i++)
            {
                //--- Assign transaction object and connection to command object for a pending local transaction ---
                _insertQry = Class1.conn.CreateCommand();
                _insertQry.Connection = Class1.conn;
                _insertQry.Transaction = myTrans;

                _insertQry.CommandText = "INSERT INTO Product_PropertyValue(ItemNo, PropertyNo, ValueNo) VALUES (@ItemNo, @PropertyNo, @ValueNo)";

                //_insertQry = new SqlCommand("INSERT INTO Product_PropertyValue(ItemNo, PropertyNo, ValueNo) VALUES (@ItemNo, @PropertyNo, @ValueNo)", Class1.conn);

                _insertQry.Parameters.AddWithValue("@ItemNo", _itemNo[i]);
                _insertQry.Parameters.AddWithValue("@PropertyNo", _propNo);
                _insertQry.Parameters.AddWithValue("@ValueNo", _propValue);

                _insertQry.ExecuteNonQuery();
            }
        }
        catch (Exception ex)
        {
            success = false;
            myTrans.Rollback();
        }

        if (success)
        {
            myTrans.Commit();
        }

如果这不起作用,请告诉我。

于 2012-04-13T20:11:07.810 回答
0

您走在正确的道路上,ADO.NET 支持事务,因此您将能够回滚错误。

在此处发布您的代码将为您提供更具体的指导;但是,由于您的问题非常笼统,我鼓励您遵循 MSDN 提供的模板

using (SqlConnection connection = new SqlConnection(connectionString))
{
    connection.Open();

    // Start a local transaction.
    SqlTransaction sqlTran = connection.BeginTransaction();

    // Enlist a command in the current transaction.
    SqlCommand command = connection.CreateCommand();
    command.Transaction = sqlTran;

    try
    {
        // Execute two separate commands.
        command.CommandText =
          "INSERT INTO Production.ScrapReason(Name) VALUES('Wrong size')";
        command.ExecuteNonQuery();
        command.CommandText =
          "INSERT INTO Production.ScrapReason(Name) VALUES('Wrong color')";
        command.ExecuteNonQuery();

        // Commit the transaction.
        sqlTran.Commit();
        Console.WriteLine("Both records were written to database.");
    }
    catch (Exception ex)
    {
        // Handle the exception if the transaction fails to commit.
        Console.WriteLine(ex.Message);

        try
        {
            // Attempt to roll back the transaction.
            sqlTran.Rollback();
        }
        catch (Exception exRollback)
        {
            // Throws an InvalidOperationException if the connection 
            // is closed or the transaction has already been rolled 
            // back on the server.
            Console.WriteLine(exRollback.Message);
        }
    }
} 
于 2012-04-13T19:42:36.607 回答