Go + Bun におけるトランザクション戦略
Go
Bun
以下記事を参考にした。
https://zenn.dev/shiroemons/scraps/de5ef24724b715
transaction.go
type txKey struct{}
var TxCtxKey = txKey{}
type TxRepository struct {
db *bun.DB
}
func NewTxRepository(db *bun.DB) common.TxRepository {
return &TxRepository{db: db}
}
func (r *TxRepository) RunInTx(ctx context.Context, opts *sql.TxOptions, fn func(ctx context.Context) error) error {
tx, err := r.db.BeginTx(ctx, opts)
if err != nil {
return err
}
c := context.WithValue(ctx, TxCtxKey, tx)
var done bool
defer func() {
if !done {
_ = tx.Rollback()
}
}()
if err := fn(c); err != nil {
return err
}
done = true
return tx.Commit()
}
使い方の例
err = i.TxRepository.RunInTx(ctx, &sql.TxOptions{}, func(ctx context.Context) error {
user.SetRemoveKey()
_, err = i.UserRepository.Update(ctx, *user)
if err != nil {
return err
}
err := i.UserRepository.Delete(ctx, id)
if err != nil {
return err
}
return nil
})