Как справиться с ошибкой фиксации / отката GORM

#go #transactions #go-gorm

# #Вперед #транзакции #go-gorm

Вопрос:

Я только что обнаружил, что в GORM фиксация транзакции может возвращать ошибку, например:

 tx := db.begin()
// do somthing here
err := tx.Commit().Error
 

Также она появляется при откате

 tx := db.begin()
// do somthing here
err := tx.Rollback().Error
 

Интересно, как произойдет эта ошибка?

И если это произойдет, будет ли сам GORM выполнять какие-либо функции восстановления для обработки ожидающих транзакций?

Или мне нужно что-то сделать, если откат или фиксация возвращает ошибку?

Кстати, есть ли какие-либо рекомендации по решению таких проблем с транзакциями в GORM?

Ответ №1:

Интересно, как произойдет эта ошибка?

Точно в тех же ситуациях, когда вы можете получить ошибку от какого-либо другого вызова базы данных:

  • Сбой сетевого подключения
  • Сбой базы данных, диска или оборудования
  • Проблемы с разрешениями
  • Синтаксические ошибки в команде
  • Ошибки несоответствия данных

Поскольку Begin ваши варианты ошибок несколько ограничены, поскольку нет данных (пока), которые могли бы быть противоречивыми. Но Commit Rollback возможны любые из этих ошибок, а также случай, когда активная транзакция не должна быть зафиксирована (из-за предыдущей ошибки, потому что она уже была зафиксирована или потому, что она уже была откатана).

И если это произойдет, будет ли сам GORM выполнять какие-либо функции восстановления для обработки ожидающих транзакций?

Нет. ГОРМ не может этого сделать, поскольку он не знает логику вашего приложения. Как и во всех сбоях всех типов, программист должен определить, какое действие является подходящим. Возможно, вам следует повторить попытку. Возможно, вам следует повторить попытку только N раз. Возможно, вам следует проигнорировать сбой и продолжить, как если бы это удалось. Возможно, вам следует вернуть ошибку пользователю. Возможно, вам следует запаниковать и завершить работу всей программы. Очевидно, что GORM не может узнать правильный ответ.

Или мне нужно что-то сделать, если откат или фиксация возвращает ошибку?

Как упоминалось в моем последнем абзаце, только вы можете это знать. Что пытается сделать ваше приложение? Что правильно делать в случае сбоя?

Кстати, есть ли какие-либо рекомендации по решению таких проблем с транзакциями в GORM?

Это не имеет никакого отношения к GORM. «Лучшая практика» при обработке ошибок — просто рассуждать о том, что указывает ошибка, и что ваше приложение должно делать в этом случае.

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

1. Кажется, я пренебрегаю обработкой ошибок раньше. Грустно: / Нужно следовать моей бизнес-логике, чтобы переписать часть фиксации и отката. Спасибо за ваш подробный ответ!

2. @Lo1nt: Это урок, который каждый разработчик в конечном итоге усваивает на собственном горьком опыте. Хотя лучше узнать об этом раньше, чем позже 🙂

3. Да! мне еще предстоит пройти долгий путь: 3

Ответ №2:

Вот код для

 func (db *DB) Rollback() *DB {
    if committer, ok := db.Statement.ConnPool.(TxCommitter); ok amp;amp; committer != nil {
        if !reflect.ValueOf(committer).IsNil() {
            db.AddError(committer.Rollback())
        }
    } else {
        db.AddError(ErrInvalidTransaction)
    }
    return db
}
 

Таким образом, это проверяет только, сгенерирован ли tx экземпляр из Begin() метода и не является ли он обычным *gorm.DB экземпляром. Таким образом, в случае отката проверка ошибок не имеет решающего значения (но, конечно, рекомендуется)

.Commit() Конечно, вы должны проверять ошибки, потому что фиксация выполняет все ваши взаимодействия с базой данных во время транзакций. Поэтому, если какой-либо из них вернет ошибку .Commit() error, вы получите к ней доступ.

Вот пример его использования из документации https://gorm.io/docs/transactions.html#A-Specific-Example