寻找有关如何正确处理数据库对象以及可能需要清理的建议

时间:2016-05-18 17:30:31

标签: c# ado.net db2

每当用户“更新”记录时,我都试图在单个事务中对数据库表执行两次更新。首先,我通过将取消日期设置为生效日期来“取消”原始记录。然后,我输入一个包含所提供值的新记录。这就是我们记录更新历史的方式。

我正在寻找有关如何正确处理数据库对象以及可能需要清理的建议。例如,我的“使用”块是否合理?我是否可以假设在事务启动后发生了隐含的回滚,但在事务开始后出现问题?

    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?
        }
    }

1 个答案:

答案 0 :(得分:1)

您的一次性物品都被正确包裹在using区块中,这样即使在例外的情况下它们也会被处理掉。

由于命令包含在事务中,因此在提交事务之前不会提交它们。如果第一个命令执行但第二个命令抛出异常,那么事务将不会被提交。

如果事务未提交,documentation表示显式回滚事务。

sqltransaction.Rollback();