Что произойдет, если транзакция.Откат / фиксация никогда не вызывались перед закрытием соединения?

#mysql #asp.net #commit #rollback

#mysql #asp.net #фиксация #Откат

Вопрос:

Что произойдет, если транзакция.Откат / фиксация никогда не вызывались перед закрытием соединения?

 public DBStatus InsertUpdateUserProfile(Int64 UserID, W_User_Profile oUser)
{
    MySqlConnection oMySQLConnecion = null;
    MySqlTransaction tr = null;
    DBStatus oDBStatus = new DBStatus();
    try
    {
        oMySQLConnecion = new MySqlConnection(DatabaseConnectionString);
        if (oMySQLConnecion.State == System.Data.ConnectionState.Closed || oMySQLConnecion.State == System.Data.ConnectionState.Broken)
        {
            oMySQLConnecion.Open();
        }

        tr = oMySQLConnecion.BeginTransaction();

        if (oMySQLConnecion.State == System.Data.ConnectionState.Open)
        {
            string Query = @"INSERT INTO user .....................;"
                            INSERT IGNORE INTO user_role ....................;";

            MySqlCommand oCommand = new MySqlCommand(Query, oMySQLConnecion);
            oCommand.Transaction = tr;

            oCommand.Parameters.AddWithValue("@UserID", UserID);                            
            oCommand.Parameters.AddWithValue("@AddressID", oUser.AddressID);                                 
    ................
    ................


            int sqlSuccess = oCommand.ExecuteNonQuery();

            if (sqlSuccess>0)
            {
                tr.Commit();
                oDBStatus.Type = DBOperation.SUCCESS;
                oDBStatus.Message.Add(DBMessageType.SUCCESSFULLY_DATA_UPDATED);
            }
            oMySQLConnecion.Close();
        }
        else
        {
            oDBStatus.Type = DBOperation.ERROR;
            oDBStatus.Message.Add(DBMessageType.ERROR_DUE_TO_NO_DB_CONNECTION);
        }
        return oDBStatus;
    }
    catch (Exception ex)
    {
        if (oMySQLConnecion.State == System.Data.ConnectionState.Open)
        {
            tr.Rollback();
            oMySQLConnecion.Close();
        }
        oDBStatus.Type = DBOperation.ERROR;
        oDBStatus.Message.Add(DBMessageType.ERROR_OR_EXCEPTION_OCCURED_WHILE_UPDATING);
        oDBStatus.InnerException.Add(ex.Message);
        return oDBStatus;
    }
} 
  

В приведенной выше функции я выполняю фиксацию, если транзакция прошла успешно, и откат, если она завершилась неудачей, а соединение все еще включено.

Если соединение прервано, отката не происходит. Я прочитал много мест, в которых говорится, что это будет автоматический откат, если соединение завершится без фиксации (чего я хочу). Это плохая практика? Я мог бы добавить try-catch после установления соединения, но добавить немного кода во все подобные функции. Действительно ли это необходимо?

Комментарии:

1. Не вызывать Close . Используйте using . Он вызовет Dispose, и dispose откатит незавершенную транзакцию. Это обычная практика. Было бы невозможно обработать определенные сценарии, если бы он не откатил их при Dispose.

Ответ №1:

Что произойдет, если транзакция.Откат / фиксация никогда не вызывались перед закрытием соединения?

В MySQL транзакция откатывается. Но некоторые другие серверы таблиц фиксируют это при закрытии соединения.

Профессиональный совет: не полагайтесь на это поведение, кроме как на способ справиться с жестким сбоем.

Комментарии:

1. @PrakashMhasavekar Я думаю, вы имеете в виду внутри блока Catch для отката. Если вы сделали это внутри блока Finally, то он всегда будет пытаться выполнить откат, даже при успешном выполнении.

2. @J.D. Моя ошибка. Это должно быть Try { Commit; } Catch { Rollback; } Finally { Dispose; }