# #postgresql #go #go-gorm
Вопрос:
В моем проекте golang, использующем gorm в качестве ORM и posgress в качестве базы данных, в некоторых ситуациях, когда я начинаю транзакцию для изменения трех таблиц и фиксации, меняется только одна из таблиц. данные двух других таблиц не меняются. есть идеи, как это может произойти?
вы можете увидеть пример ниже
o := *gorm.DB
tx := o.Begin()
invoice.Number = 1
err := tx.Save(amp;invoice)
if err != nil {
err2 := tx.RollBack().Error()
return err
}
receipt.Ref = "1331"
err = tx.Save(amp;receipt)
if err != nil {
err2 := tx.RollBack().Error()
return err
}
payment.status = "succeed"
err = tx.Save(amp;payment)
if err != nil {
err2 := tx.RollBack().Error()
return err
}
err = tx.Commit()
if err != nil {
err2 := tx.Rollback()
return err
}
Просто изменились платежные данные, и я не получаю никаких ошибок.
Комментарии:
1. Во второй строке разве tx не должен создаваться из БД? Нравится
tx := o.Begin()
2. да, я должен отредактировать это здесь… спасибо.
3. Компилируется ли вообще этот код? У вас есть сочетание отката и отката, вы вызываете
tx.Error
элемент как функцию. После каждого сохранения вы назначаетеtx.Save(*)
err
, а затем возвращаете его из функции, даже еслиtx.Save
возвращает*gorm.DB
значение, несовместимое с интерфейсом ошибок.
Ответ №1:
Очевидно, вы ошибочно используете очки сохранения! В PostgreSQL у нас могут быть вложенные транзакции, то есть определение точек сохранения позволяет разделить транзакцию на части. Я не программист Golang, и мой основной язык не Go, но, как я предполагаю, проблема в «tx.save», который создает точку сохранения и не сохраняет данные в базу данных. Точки сохранения создают новую точку сохранения транзакции, и, таким образом, последняя таблица фиксируется.
Комментарии:
1. эта ошибка возникает не всегда, и точка сохранения не поддерживается в моей версии gorm(v1). Метод Save() работает так же, как показано ниже в gorm:
db.First(amp;user) user.Name = "jinzhu 2" user.Age = 100 db.Save(amp;user) //// UPDATE users SET name='jinzhu 2', age=100, birthday='2016-01-01', updated_at = '2013-11-17 21:34:10' WHERE id=111
Ответ №2:
Если вы знакомы с Node.js, затем любой обратный вызов асинхронной функции возвращает ошибку в качестве первого аргумента. В Go мы следуем той же норме.