使用 SqlTransaction 提交多个 SqlCommand
Commit multiple SqlCommands with SqlTransaction
我正在尝试将 SqlCommand
的列表传递到一个成员函数中,该成员函数保持与数据库的连接。
public void CommitAsTransaction(List<SqlCommand> commands) {
SqlTransaction transaction = null;
SqlConnection connection = null;
try {
connection = this.CreateSqlConnection();
connection.Open();
transaction = connection.BeginTransaction("TransactionID");
foreach (SqlCommand cmd in commands) {
cmd.Transaction = transaction;
cmd.Connection = connection;
cmd.ExecuteNonQuery();
}
transaction.Commit();
}
catch (Exception ex) {
transaction.Rollback();
}
connection.Close();
}
这是我目前拥有的。发生错误是因为该命令似乎正在按原样执行并且从未达到 transaction.Commit();
。我见过很多人这样做,但我不确定我做错了什么。
PS:问题是将要执行的存储过程必须全部 运行 在单个事务中,我不控制这些并且它们是加密的,原因是它们must be 运行 in a transaction 是因为他们在具有 PK 要求的 table 中创建临时记录。
您可以改用事务范围吗?
类似于:
// place this code inside CommitAsTransaction
using (TransactionScope scope = new TransactionScope())
{
Boolean AllOK = true;
SqlConnection connection = this.CreateSQLConnection();
try
{
connection.Open()
}
catch (Exception e)
{
// deal with it how you need to
AllOK = false;
}
if (AllOK)
{
foreach(SQlCommand cmd in Commands)
{
try
{
cmd.Connection = connection;
cmd.ExecuteNonQuery();
}
catch (Exception e)
{
// Deal with it..
AllOK = false;
break;
}
}
if (AllOK)
{
scope.Complete();
try
{
connection.Close();
}
catch (Exception e)
{
// deal with it
}
}
}
}
非常感谢。我最终根据其他人的综合答案自己弄清楚了,谢谢,这是我使用的代码:
public List<Models.eConnectModels.eConnStatus> CommitAsTransaction(List<SqlCommand> commands)
{
SqlTransaction transaction = null;
SqlConnection connection = null;
List<eConnStatus> ErrorList = new List<eConnStatus>();
try
{
connection = this.CreateSqlConnection();
connection.Open();
transaction = connection.BeginTransaction(IsolationLevel.ReadUncommitted, "TransactionID");
foreach (SqlCommand cmd in commands)
{
eConnStatus curErr = new eConnStatus();
cmd.Transaction = transaction;
cmd.Connection = connection;
SqlParameter errorString = cmd.Parameters.Add("@oErrString", SqlDbType.VarChar);
errorString.Direction = ParameterDirection.Output;
errorString.Size = 8000;
SqlParameter errorStatus = cmd.Parameters.Add("@O_iErrorState", SqlDbType.Int);
errorStatus.Direction = ParameterDirection.Output;
cmd.ExecuteNonQuery();
curErr.ErrorState = (int)cmd.Parameters["@O_iErrorState"].Value;
curErr.ErrorMessage = (string)cmd.Parameters["@oErrString"].Value;
ErrorList.Add(curErr);
}
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
connection.Close();
throw ex;
}
connection.Close();
return ErrorList;
}
我正在尝试将 SqlCommand
的列表传递到一个成员函数中,该成员函数保持与数据库的连接。
public void CommitAsTransaction(List<SqlCommand> commands) {
SqlTransaction transaction = null;
SqlConnection connection = null;
try {
connection = this.CreateSqlConnection();
connection.Open();
transaction = connection.BeginTransaction("TransactionID");
foreach (SqlCommand cmd in commands) {
cmd.Transaction = transaction;
cmd.Connection = connection;
cmd.ExecuteNonQuery();
}
transaction.Commit();
}
catch (Exception ex) {
transaction.Rollback();
}
connection.Close();
}
这是我目前拥有的。发生错误是因为该命令似乎正在按原样执行并且从未达到 transaction.Commit();
。我见过很多人这样做,但我不确定我做错了什么。
PS:问题是将要执行的存储过程必须全部 运行 在单个事务中,我不控制这些并且它们是加密的,原因是它们must be 运行 in a transaction 是因为他们在具有 PK 要求的 table 中创建临时记录。
您可以改用事务范围吗? 类似于:
// place this code inside CommitAsTransaction
using (TransactionScope scope = new TransactionScope())
{
Boolean AllOK = true;
SqlConnection connection = this.CreateSQLConnection();
try
{
connection.Open()
}
catch (Exception e)
{
// deal with it how you need to
AllOK = false;
}
if (AllOK)
{
foreach(SQlCommand cmd in Commands)
{
try
{
cmd.Connection = connection;
cmd.ExecuteNonQuery();
}
catch (Exception e)
{
// Deal with it..
AllOK = false;
break;
}
}
if (AllOK)
{
scope.Complete();
try
{
connection.Close();
}
catch (Exception e)
{
// deal with it
}
}
}
}
非常感谢。我最终根据其他人的综合答案自己弄清楚了,谢谢,这是我使用的代码:
public List<Models.eConnectModels.eConnStatus> CommitAsTransaction(List<SqlCommand> commands)
{
SqlTransaction transaction = null;
SqlConnection connection = null;
List<eConnStatus> ErrorList = new List<eConnStatus>();
try
{
connection = this.CreateSqlConnection();
connection.Open();
transaction = connection.BeginTransaction(IsolationLevel.ReadUncommitted, "TransactionID");
foreach (SqlCommand cmd in commands)
{
eConnStatus curErr = new eConnStatus();
cmd.Transaction = transaction;
cmd.Connection = connection;
SqlParameter errorString = cmd.Parameters.Add("@oErrString", SqlDbType.VarChar);
errorString.Direction = ParameterDirection.Output;
errorString.Size = 8000;
SqlParameter errorStatus = cmd.Parameters.Add("@O_iErrorState", SqlDbType.Int);
errorStatus.Direction = ParameterDirection.Output;
cmd.ExecuteNonQuery();
curErr.ErrorState = (int)cmd.Parameters["@O_iErrorState"].Value;
curErr.ErrorMessage = (string)cmd.Parameters["@oErrString"].Value;
ErrorList.Add(curErr);
}
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
connection.Close();
throw ex;
}
connection.Close();
return ErrorList;
}