C# 使用try-catch最干净地使用BeginTransaction

C# 使用try-catch最干净地使用BeginTransaction,c#,transactions,C#,Transactions,到目前为止,我使用两个try-catch块进行查询。如果未建立连接,第一个将抛出错误。第二个检查SqlCommand是否成功执行。就像下面的例子 try { using(varconnection=newSqlConnection()) using(varcmd=newSqlCommand()) { connection.Open(); var transaction=connection.BeginTransaction(); cmd.Connecti

到目前为止,我使用两个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{}
   }
 }
}

他们两个有相同的结果吗?两种方法中哪一种更可取?

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

最好的方法是也使用将
事务
放入
中,我们还应该为查询使用一个参数:

使用(var连接=新的SqlConnection(connString))
使用(var cmd=new SqlCommand(“插入到客户(名称)值(@Name));”)
{
var param=cmd.Parameters.Add(“@Name”,SqlDbType.VarChar,在此处插入列长度);
connection.Open();
使用(var transaction=connection.BeginTransaction())
{
cmd.Transaction=Transaction;
参数值=“Dimitri”;
cmd.ExecuteNonQuery();
param.Value=“乔治”;
cmd.ExecuteNonQuery();
Commit();
}
}

通过查看,我们可以看到,如果尚未提交,则处理事务对象将自动回滚。因此,使用
将清理一切


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

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

最好的方法是也使用
事务
放入
中,我们还应该为查询使用一个参数:

使用(var连接=新的SqlConnection(connString))
使用(var cmd=new SqlCommand(“插入到客户(名称)值(@Name));”)
{
var param=cmd.Parameters.Add(“@Name”,SqlDbType.VarChar,在此处插入列长度);
connection.Open();
使用(var transaction=connection.BeginTransaction())
{
cmd.Transaction=Transaction;
参数值=“Dimitri”;
cmd.ExecuteNonQuery();
param.Value=“乔治”;
cmd.ExecuteNonQuery();
Commit();
}
}

通过查看,我们可以看到,如果尚未提交,则处理事务对象将自动回滚。因此,使用
将清理一切


如果您需要捕获以向用户显示消息,请在代码之外执行操作,即在整个内容周围放置
try/catch
。如果
connection.Open(),不要自己清理代码
抛出,则对
事务无效。回滚
,它将抛出一个
NullReferenceException
(这将被第二个
try…catch
)捕获。@xanatos在这种情况下。。。在第一种情况下,open是在“rollback”捕获之外的,在第二种情况下,有一个guardnor更可取,即使您坚持使用显式事务,您的代码也过于冗长。首先查找
TransactionScope
。在任何情况下,都几乎不需要显式的
事务.Rollback()
,因为如果在处理事务时未调用
.Commit()
(您应该在
块中使用
执行此操作),则回滚会自动发生。@Selvin在第一个中,执行
事务.Rollback()
相信
交易是
!=空
。。。我甚至看到(相当于第二个)
transaction?.Rollback()
around。。。但杰罗恩的建议要好得多<代码>在任何地方使用
都是纠正.NET编程的关键--相信事务是正确的!=null,因为它将不为null<代码>连接。BeginTransaction
将返回非空事务或抛出。。。但如果抛出,那么执行将以外部空捕获结束,并且永远不会击中rolback。。。当
connection.Open
将通过
connection.Open()时,情况也是如此
抛出,则对
事务无效。回滚
,它将抛出一个
NullReferenceException
(这将被第二个
try…catch
)捕获。@xanatos在这种情况下。。。在第一种情况下,open是在“rollback”捕获之外的,在第二种情况下,有一个guardnor更可取,即使您坚持使用显式事务,您的代码也过于冗长。首先查找
TransactionScope
。在任何情况下,都几乎不需要显式的
事务.Rollback()
,因为如果在处理事务时未调用
.Commit()
(您应该在
块中使用
执行此操作),则回滚会自动发生。@Selvin在第一个中,执行
事务.Rollback()
相信
交易是
!=空
。。。我甚至看到(相当于第二个)
transaction?.Rollback()
around。。。但杰罗恩的建议要好得多<代码>在任何地方使用
都是纠正.NET编程的关键--相信事务是正确的!=null,因为它将不为null<代码>连接。BeginTransaction
将返回非空事务或抛出。。。但如果抛出,那么执行将以外部空捕获结束,并且永远不会击中rolback。。。连接时发生了相同的情况。打开时会出现问题吗?我应该在哪里放置try and catch?在连接打开之前?您不应该
尝试
捕获
任何内容<代码>使用
将处理所有问题。如果发生异常怎么办?
使用
将清除所有问题。如果您需要捕获以向用户显示消息,请在代码之外执行,即在整个内容周围放置一个
try/catch
。不要自己做清理代码这是毫无意义的。如果出现问题,您需要放置try-and-catch进行回滚。transaction.RollBack()。除外