我有一些混乱,我想清除它 - 我使用ADO.NET将值插入数据库。假设我在插入第5项数据时遇到错误,我想插入10项,它应该回滚我插入到数据库中的任何内容。
我刚刚阅读了Transaction和Rollback方法的概念,并尝试在程序中实现它但仍然插入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();
}
任何人都可以帮助我吗?
答案 0 :(得分: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
答案 1 :(得分:1)
我对您的代码进行了2次修改
1)将BeginTransaction()移到for循环之外,以便所有10个INSERt语句都在一个事务中,如果你想要它们是 atomic
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();
}
如果这不起作用,请告诉我。
答案 2 :(得分: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);
}
}
}