postgres не сохраняет все данные после фиксации

# #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 мы следуем той же норме.

https://medium.com/rungo/error-handling-in-go-f0125de052f0