使用 try catch 使用 BeginTransaction 的最简洁方法

Cleanest way to use BeginTransaction using try catch

到目前为止,我正在使用两个 try catch 块来进行查询。如果未建立连接,第一个将抛出错误。第二个检查 SqlCommand 是否执行成功。像下面的例子

try
{
  using(varconnection=newSqlConnection())
  using(varcmd=newSqlCommand())
  {
  
    connection.Open();
    var transaction=connection.BeginTransaction();
    cmd.Connection=connection;
    cmd.Transaction=transaction;

    try
    {
     cmd.CommandText="InsertintoCustomers(Name)values('Dimitri')";
     cmd.ExecuteNonQuery();

     cmd.CommandText="InsertintoCustomers(Name)values('George')";
     cmd.ExecuteNonQuery();

     transaction.Commit();
   }
   catch
   {
     try{transaction.Rollback();}catch{}
   }
  }
}
catch
{

}

我找到了第二个对我来说更清晰的示例。

SqlTransactiontransaction=null;
using(varconnection=newSqlConnection())
using(varcmd=newSqlCommand())
{
   try
   {
   connection.Open();
   transaction=connection.BeginTransaction();
   cmd.Connection=connection;
   cmd.Transaction=transaction;

   cmd.CommandText="InsertintoCustomers(Name)values('Dimitri')";
   cmd.ExecuteNonQuery();

   cmd.CommandText="InsertintoCustomers(Name)values('George')";
   cmd.ExecuteNonQuery();

   transaction.Commit();
   transaction.Dispose();
   transaction=null;
}
catch
{
   if(transaction!=null)
   {
      try{transaction.Rollback();}catch{}
   }
 }
}

两者的结果一样吗?两者哪个更好?

这两种方法都不好。它们太冗长了。

最好的方法是把Transaction也放在using中,同时我们应该使用一个参数来查询:

using(var connection = new SqlConnection(connString))
using(var cmd = new SqlCommand("Insert into Customers (Name) values (@Name));"))
{
    var param = cmd.Parameters.Add("@Name", SqlDbType.VarChar, insert_column_length_here);
    connection.Open();
    using(var transaction = connection.BeginTransaction())
    {
        cmd.Transaction = transaction;
        param.Value = "Dimitri";
        cmd.ExecuteNonQuery();

        param.Value = "George";
        cmd.ExecuteNonQuery();

        transaction.Commit();
    }
}

通过查看 the source code 我们可以看到,如果尚未提交,处理事务对象将自动回滚。所以 using 将清理所有内容。

如果您需要捕获以向用户显示消息,请在代码外部 执行,即在整个内容周围放置一个 try/catch。不要自己做清理代码