ユーザーがレコードを「更新」するたびに、データベーステーブルを1回のトランザクションで2回更新しようとしています。最初に、キャンセル日付を有効日付に設定して元のレコードを「キャンセル」します。次に、値を指定して新しいレコードを入力します。これは更新履歴を記録する方法です。データベースオブジェクトを適切に処分する方法と必要なクリーンアップについてのアドバイスを探します
私は、データベースオブジェクトを適切に処分する方法と、必要なクリーンアップについてのアドバイスを探しています。たとえば、私の「使用する」ブロックは合理的ですか?トランザクションが開始されたにもかかわらず、トランザクションが開始された後で何かがうまくいかない場合、暗黙のロールバックが発生すると想定できますか?彼らもさえ例外の中に、配置された取得するつもりだので
public void UpdateStateAssessment(Models.StateAssessment stateAssessment)
{
string updateSql = @"UPDATE GSAS.ST_ASSMT_REF
SET
CAN_DT = EFF_DT
WHERE
VENDR_ID = @VENDR_ID AND
EFF_DT = @EFF_DT AND
LAST_TS = @LAST_TS";
string insertSql = @"INSERT INTO GSAS.ST_ASSMT_REF
(
VENDR_ID
,ST_ASSMT_NM
,ST_CD
,EFF_DT
,CAN_DT
,LAST_TS
,LAST_OPER_ID
)
VALUES
(
@VENDR_ID
,@ST_ASSMT_NM
,@ST_CD
,@EFF_DT
,@CAN_DT
,CURRENT TIMESTAMP
,@LAST_OPER_ID
)";
try
{
using (var connection = OpenConnection())
{
DB2Transaction sqltransaction = connection.BeginTransaction(IsolationLevel.ReadCommitted);
using (sqltransaction)
{
using (DB2Command cmd = connection.CreateCommand())
{
cmd.CommandText = updateSql;
cmd.CommandType = CommandType.Text;
cmd.Transaction = sqltransaction;
cmd.Connection = connection;
cmd.Parameters.Add(new DB2Parameter("@CAN_DT", DB2Type.Date) { Value = stateAssessment.CancelDate.Date });
cmd.Parameters.Add(new DB2Parameter("@VENDR_ID", DB2Type.Char) { Value = stateAssessment.VendorId });
cmd.Parameters.Add(new DB2Parameter("@EFF_DT", DB2Type.Date) { Value = stateAssessment.EffectiveDate.Date });
cmd.Parameters.Add(new DB2Parameter("@LAST_TS", DB2Type.DateTime) { Value = stateAssessment.LastTimestamp });
cmd.ExecuteNonQuery();
}
using (DB2Command cmd = connection.CreateCommand())
{
cmd.CommandText = insertSql;
cmd.CommandType = CommandType.Text;
cmd.Transaction = sqltransaction;
cmd.Connection = connection;
cmd.Parameters.Add(new DB2Parameter("@ST_ASSMT_NM", DB2Type.Char) { Value = stateAssessment.Name });
cmd.Parameters.Add(new DB2Parameter("@ST_CD", DB2Type.Char) { Value = stateAssessment.StateCode });
cmd.Parameters.Add(new DB2Parameter("@CAN_DT", DB2Type.Date) { Value = stateAssessment.CancelDate.Date });
cmd.Parameters.Add(new DB2Parameter("@LAST_OPER_ID", DB2Type.Char) { Value = stateAssessment.LastOperatorId });
cmd.Parameters.Add(new DB2Parameter("@VENDR_ID", DB2Type.Char) { Value = stateAssessment.VendorId });
cmd.Parameters.Add(new DB2Parameter("@EFF_DT", DB2Type.Date) { Value = stateAssessment.EffectiveDate.Date });
cmd.ExecuteNonQuery();
}
sqltransaction.Commit();
}
}
}
catch (Exception exception)
{
//Log the error.
//Any Cleaning up to do?
}
}
その後、私はそれが外側のブロックであると私はロールバックする前に、それがnullでないかどうかを確認する必要がありますのでのSqlTransactionオブジェクトの宣言を移動する必要があります。おそらく、ロールバックしようとする前に、トランザクションが開始されたかどうかを確認する方法もあります。だからこそ私は、使用ブロックがロールバックを処理することを望んでいたのです。 – ChadD
このコマンドを使用する場合と同様に、usingステートメントでトランザクションを作成することもできます( 'use(var sqltransaction = connection.BeginTransaction(IsolationLevel.ReadCommitted))')。その後、try/catchを配置します。例外がスローされた場合は、トランザクションが範囲外になる前にロールバックします。 –