3 回答

TA貢獻(xiàn)1921條經(jīng)驗(yàn) 獲得超9個(gè)贊
經(jīng)過大量的挖掘和調(diào)試,我想出了這個(gè)解決方案:
您首先需要以正確的順序注冊(cè)您的插件執(zhí)行,在我的情況下應(yīng)該是這樣的:
gormDb.Callback().Create().Before("gorm:commit_or_rollback_transaction").Register("changelog_create", ChangelogCreatePlugin)
此命令將保證您的插件將在模型的任何插入子句的事務(wù)提交之前被激活或觸發(fā)。
要了解有關(guān)在何處注冊(cè)插件的更多信息,請(qǐng)查看在 gorm 中注冊(cè)的默認(rèn)回調(diào)
這樣做之后,我需要調(diào)整插件代碼:
func ChangelogCreatePlugin(db *gorm.DB) {
// first make a check that the model insert transaction doesn't have any error
if db.Error != nil {
return
}
log := &Log{NewValue: "the new value", OldValue: "the old value", CreatedAt: "current time"}
// get a new db session for the new model to work
logDb := db.Session(&gorm.Session{})
// if an error ocurred while saving the log
// push it into original model db instance errors, so it will be rolledback eventually
logErr := logDb.Save(log)
if logErr != nil {
db.AddError(logErr)
}
}
希望有一天這可以幫助某人!

TA貢獻(xiàn)1821條經(jīng)驗(yàn) 獲得超5個(gè)贊
嘗試創(chuàng)建事務(wù)性decorator女巫使用func(d *gorm.DB)或f ...func(d *gorm.DB)作為參數(shù)。它應(yīng)該看起來(lái)像
type TransactionalDecorator struct {
DB *gorm.DB
}
func (t *TransactionalDecorator) Transaction(f ...func(d *gorm.DB) error) error {
return t.DB.Transaction(func(tx *gorm.DB) error {
for _, fn := range f {
if err := fn(tx); err != nil {
return err
}
}
return nil
})
}
所有數(shù)據(jù)庫(kù)交互功能將在同一個(gè)事務(wù)中執(zhí)行
repo , _ := gorm.Open(...)
tdb := &TransactionalDecorator{DB: repo}
saveModel := func(d *gorm.DB) error {
// save model
}
saveLog := func(d *gorm.DB) error {
// save log
}
err := tdb.Transaction(saveModel, saveLog)

TA貢獻(xiàn)1828條經(jīng)驗(yàn) 獲得超3個(gè)贊
怎么樣:
func ChangelogCreatePlugin(db *gorm.DB) {
log := &Log{NewValue: "the new value", OldValue: "the old value", CreatedAt: "current time"}
// Here is the problem
db.Session(&gorm.Session{}).Save(log)
}
這應(yīng)該給你一個(gè)“新鮮”的 db/tx 來(lái)使用
- 3 回答
- 0 關(guān)注
- 243 瀏覽
添加回答
舉報(bào)