trycatchを使用してBeginTransactionを使用する最もクリーンな方法
今まで、クエリに2つのtrycatchブロックを使用しています。接続が確立されていない場合、最初のものはエラーをスローします。2つ目は、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
{
}
私にとってより明確に見える2番目の例を見つけました。
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{}
}
}
}
どちらも同じ結果になっていますか?2つのうちどちらがより好ましいですか?
回答
2 Charlieface
これらの2つの方法はどちらも適切ではありません。それらは冗長すぎます。
最良の方法は、もに入れること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();
}
}
ソースコードを見ると、トランザクションオブジェクトを破棄すると、まだコミットされていない場合は自動的にロールバックされることがわかります。だから、using
すべてをクリーンアップします。
ユーザーにメッセージを表示するためにキャッチする必要がある場合は、コードの外でそれを実行します。つまりtry/catch
、全体を囲みます。クリーンアップコードを自分で実行しないでください