-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtx.go
57 lines (50 loc) · 894 Bytes
/
tx.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package exql
import (
"context"
"database/sql"
"golang.org/x/xerrors"
)
type Tx interface {
Saver
Finder
Mapper
Tx() *sql.Tx
}
type tx struct {
*saver
*finder
*mapper
tx *sql.Tx
}
func newTx(t *sql.Tx) *tx {
return &tx{saver: newSaver(t), finder: newFinder(t), mapper: &mapper{}, tx: t}
}
func (t *tx) Tx() *sql.Tx {
return t.tx
}
func Transaction(db *sql.DB, ctx context.Context, opts *sql.TxOptions, callback func(tx Tx) error) error {
sqlTx, err := db.BeginTx(ctx, opts)
if err != nil {
return err
}
tx := newTx(sqlTx)
var p interface{}
txErr := func() error {
defer func() {
p = recover()
}()
return callback(tx)
}()
if p != nil {
txErr = xerrors.Errorf("recovered: %s", p)
}
if txErr != nil {
if err := sqlTx.Rollback(); err != nil {
return err
}
return txErr
} else if err := sqlTx.Commit(); err != nil {
return err
}
return nil
}