Skip to content

Instantly share code, notes, and snippets.

@danielsaul
Last active October 11, 2018 03:29
Show Gist options
  • Select an option

  • Save danielsaul/7e5ea66643619a9505fde1dad841cad6 to your computer and use it in GitHub Desktop.

Select an option

Save danielsaul/7e5ea66643619a9505fde1dad841cad6 to your computer and use it in GitHub Desktop.
Go db store transaction
type Store struct {
q Querier
}
type DB interface {
Querier
Beginx() (*sqlx.Tx, error)
}
type Tx interface {
Querier
Commit() error
Rollback() error
}
type Querier interface {
Rebind(string) string
Get(dest interface{}, query string, args ...interface{}) error
MustExec(query string, args ...interface{}) sql.Result
NamedExec(query string, arg interface{}) (sql.Result, error)
Prepare(query string) (*sql.Stmt, error)
PrepareNamed(query string) (*sqlx.NamedStmt, error)
Select(dest interface{}, query string, args ...interface{}) error
}
func (s *Store) Transact(fn func(*Store) error) (err error) {
db, ok := s.q.(DB)
if !ok {
return errors.New("can only begin transaction on db type")
}
tx, err := db.Beginx()
if err != nil {
return errors.Wrap(err, "begin transaction failed")
}
defer func() {
if p := recover(); p != nil {
_ = tx.Rollback()
panic(p)
} else if err != nil {
_ = tx.Rollback()
} else {
err = tx.Commit()
if err != nil {
err = errors.Wrap(err, "committing transaction failed")
}
}
}()
err = fn(&Store{tx})
return err
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment