使用 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
。不要自己做清理代码
到目前为止,我正在使用两个 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
。不要自己做清理代码