【发布时间】:2013-12-16 14:36:33
【问题描述】:
我的代码中有 SaveListOfObjects 之类的方法,我在 foreach 循环中执行,然后将 insert 记录到 SQL Server。
当我插入的数据没有错误时,它工作得很好。但是如果发生错误,那么只有有效的数据会被插入到 SQL 中。
我想做以下事情:
- 仅在整个数据有效且插入时出现一个错误的情况下插入所有记录。
- 删除所有以前保存在 SQL 中的数据。
所以,我已经尝试过使用TransactionScope 和SqlTransaction 类,甚至使用SQL TRANSACTION,但我唯一能做的就是插入有效数据并省略无效数据。
现在,就我在网上搜索,我发现并行交易是不可能的。此外,SQL 具有禁止并行任务的隔离级别。
是否有任何可能的方法来完成 SQL 中的插入,例如 ALL 或 NOTHING?
更新:
我的代码如下:
public int Ramiz_SavePack(IPacking pack)
{
using (var conn = (SqlConnection)connector.GetConnection())
{
conn.Open();
SqlTransaction transaction;
var comm = (SqlCommand)connector.GetCommand("Ramiz_Pack_Save");
comm.CommandType = CommandType.StoredProcedure;
transaction = conn.BeginTransaction();
comm.Transaction = transaction;
int rowNum = 0;
try
{
if (!string.IsNullOrEmpty(pack.BrojKolete))
comm.Parameters.Add("@BrojKolete", SqlDbType.NVarChar).Value = pack.BrojKolete;
else
comm.Parameters.Add("@BrojKolete", SqlDbType.NVarChar).Value = DBNull.Value;
comm.Parameters.Add("@Bosanski", SqlDbType.NVarChar).Value = pack.Bosanski;
comm.Parameters.Add("@Kom", SqlDbType.Float).Value = pack.Kom;
comm.Parameters.Add("@Vrsta", SqlDbType.NVarChar).Value = pack.Vrsta;
comm.Parameters.Add("@Datum", SqlDbType.Date).Value = pack.Datum;
comm.Parameters.Add("@BrojKamiona", SqlDbType.Int).Value = pack.BrojKamiona;
rowNum = comm.ExecuteNonQuery();
transaction.Commit();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
try
{
conn.Close();
transaction.Rollback();
}
catch (Exception ex2)
{
Console.WriteLine(ex2.Message);
}
}
return rowNum;
}
}
并在这个内部调用这个方法:
var pack = new Pack();
for (int i = 1; i < lastRow; i++)
{
pack.Ramiz_SavePack(new Packing
{
BrojKolete = Convert.ToString(brojKoleteRange.Offset[i, 0].Value2),
Bosanski = Convert.ToString(nazivArtiklaRange.Offset[i, 0].Value2),
Kom = Convert.ToDouble(komRange.Offset[i, 0].Value2),
Vrsta = Convert.ToString(vrstaRange.Offset[i, 0].Value2),
BrojKamiona = int.Parse(ddlBrojKamiona.SelectedItem.Value),
Datum = Convert.ToDateTime(txtDate.Text)
});
pnlMessageSuccess.Visible = true;
}
【问题讨论】:
-
验证的条件是什么?你能分享一些你的代码吗?
-
请显示您的代码,因为如果我理解正确,正确的方法就是使用 SqlTransaction 或 TransactionScope 类。
-
你是否在事务范围内使用回滚?
-
您正在为每个项目创建单独的事务 - 您需要将循环包装在事务中或将项目集合发送到
Ramiz_SavePack方法。如果你回滚,你只是回滚一个事务。您需要在同一个事务中完成所有数据库工作 -
@Charleh。你的意思是我应该将 List
传递给 Ramiz_SavePack 方法并在里面尝试关闭我的 foreach 循环?
标签: c# sql-server insert rollback