#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