我有一个叫DbVms
的类,像这样:
public class DbVms
{
private bool insertApprovals(List<Approval> approvals, string user, SqlCommand command, out string resultDesc)
{
resultDesc = "";
bool result = false;
command.Parameters.Clear();
command.Parameters.Add("@estNo", SqlDbType.NVarChar);
command.Parameters.Add("@custID", SqlDbType.Int);
command.Parameters.Add("@brandName", SqlDbType.NVarChar);
command.Parameters.Add("@createdBy", SqlDbType.NVarChar);
try
{
// Now add the approvals back based on whats passed in.
foreach (Approval approval in approvals) // loop through approvals and do insert.
{
command.CommandText =
"INSERT INTO [Approvals] (vendorEstNo, customerID, brand, createdBy) VALUES (@estNo, @custID, @brandName, @createdBy)";
command.Parameters["@estNo"].Value = approval.vendorEstNo;
command.Parameters["@custID"].Value = Convert.ToInt32(approval.customerID);
command.Parameters["@brandName"].Value = approval.brandName;
command.Parameters["@createdBy"].Value = user;
command.ExecuteNonQuery();
}
result = true;
resultDesc = "All records are written to database.";
}
catch (Exception ex)
{
resultDesc = "insertApprovals - Threw an exception of type: " + ex.GetType();
}
return result;
}
private bool insertQualifications(List<Qualification> qualifications, string user,SqlCommand command, out string resultDesc)
{
resultDesc = "";
bool result = false;
command.Parameters.Clear();
command.Parameters.Add("@estNo", SqlDbType.NVarChar);
command.Parameters.Add("@qualityID", SqlDbType.Int);
command.Parameters.Add("@brandName", SqlDbType.NVarChar);
command.Parameters.Add("@createdBy", SqlDbType.NVarChar);
try
{
// Now add the qualifications back based on whats passed in.
foreach (Qualification qualification in qualifications) // loop through qualifications and do insert.
{
command.CommandText =
"INSERT INTO [Qualifications] (vendorEstNo, qualityID, brand, createdBy) VALUES (@estNo, @qualityID, @brandName, @createdBy)";
command.Parameters["@estNo"].Value = qualification.vendorEstNo;
command.Parameters["@qualityID"].Value = Convert.ToInt32(qualification.qualityID);
command.Parameters["@brandName"].Value = qualification.brandName;
command.Parameters["@createdBy"].Value = user;
command.ExecuteNonQuery();
}
result = true;
resultDesc = "All records are written to database.";
}
catch (Exception ex)
{
resultDesc = "insertQualifications - Threw an exception of type: " + ex.GetType();
}
return result;
}
public bool updateVendorData(string estNo, List<Approval> approvals, List<Qualification> qualifications, string user, out string resultDesc)
{
bool result = false;
resultDesc = "";
string connectionString = WebConfigurationManager.ConnectionStrings["myConn"].ConnectionString;
using(SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand cmd = connection.CreateCommand();
SqlTransaction transaction = connection.BeginTransaction("transcation1");
cmd.Connection = connection;
cmd.Transaction = transaction;
result = insertApprovals(approvals, user, cmd, out resultDesc);
if(result) // if approvals got inserted successfully insert qualifications
result = insertQualifications(qualifications, user, cmd, out resultDesc);
if (result) // if both approvals and qualifications got inserted successfully - commit transcation
{
transaction.Commit();
}
else // rollback otherwise.
{
try
{
transaction.Rollback();
resultDesc += " -- Successfully rolled back!";
}
catch (Exception ex2)
{
// This catch block will handle any errors that may have occurred
// on the server that would cause the rollback to fail, such as
// a closed connection.
resultDesc = "Rollback Exception Type: {0}" + ex2.GetType();
}
}
}
return result;
}
}
将SqlCommand
作为函数参数传递是否存在问题?我需要使其为ref / out变量吗?
我的目标是在两个单独的函数中执行两个insert语句,如果它们中的任何一个失败,我希望能够回滚整个事务。
这就是为什么我将相同的SqlCommand
变量传递给两个函数,并在其中任何一个失败时回滚事务的原因。但是我是否应该通过引用传递SqlCommand
有点困惑。
答案 0 :(得分:2)
我的目标是在两个单独的函数中执行两个insert语句,如果它们中的任何一个失败,我希望能够回滚整个事务。这就是为什么我将相同的SqlCommand变量传递给两个函数,并在其中任何一个失败时回滚事务的原因。
使用同一命令不是必需的。您需要的是相同的DbConnection
,并为每个命令分配相同的DbTransaction
。实际的命令可能应该是方法的本地命令-不需要它们转义该上下文。