我有一个有效的代码。
func (r *repoPG) WithTransaction(txFunc func() error) (err error) {
tx := db.NewTx()
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("panic: %v", r)
tx.Rollback()
} else if err != nil {
tx.Rollback()
} else {
tx.Commit()
}
}()
err = txFunc()
return
}
我想avod每次都写那么长的defer
,所以我试着写一个这样的函数:
func TxDefer(tx, err) {
if r := recover(); r != nil {
err = fmt.Errorf("panic: %v", r)
tx.Rollback()
} else if err != nil {
tx.Rollback()
} else {
tx.Commit()
}
}
使用它就像:
func (r *repoPG) WithTransaction(txFunc func() error) (err error) {
tx := db.NewTx()
defer TxDefer(tx, err)
err = txFunc()
return
}
但这是错误的,因为err
总是原始的,而不是txFunc()
的结果,对吗?
我该怎么办?
1条答案
按热度按时间vdzxcuhz1#
将错误的地址传递给函数。这允许函数访问调用方变量的当前值。它还允许函数设置变量。
回滚和提交返回错误。这些错误应该返回给调用方。
这样使用:
在上面的代码中,表达式
*perr
计算为WithTransaction
中err
的当前值。问题中err
的值是延迟时err
的值。