-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtx.go
94 lines (77 loc) · 2.2 KB
/
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package database
import (
"runtime"
"github.com/goexl/gox"
"github.com/goexl/gox/field"
"github.com/pangum/logging"
"xorm.io/xorm"
)
type (
// Tx 事务控制
Tx struct {
engine *Engine
logger *logging.Logger
}
txFun func(tx *Session) (err error)
txpFun func(tx *Session, params ...interface{}) (err error)
)
// 事务控制
func newTx(engine *Engine, logger *logging.Logger) *Tx {
return &Tx{
engine: engine,
logger: logger,
}
}
func (t *Tx) Do(fun txFun, fields ...gox.Field[any]) (err error) {
return t.do(func(tx *Session) error {
return fun(tx)
}, fields...)
}
func (t *Tx) Dop(fun txpFun, params []interface{}, fields ...gox.Field[any]) (err error) {
return t.do(func(tx *Session) error {
return fun(tx, params...)
}, fields...)
}
func (t *Tx) do(fun func(tx *Session) error, fields ...gox.Field[any]) (err error) {
session := t.engine.NewSession()
if err = t.begin(session, fields...); nil != err {
return
}
defer t.close(session, fields...)
if err = fun(&Session{Session: session}); nil != err {
t.rollback(session, fields...)
} else {
t.commit(session, fields...)
}
return
}
func (t *Tx) begin(tx *xorm.Session, fields ...gox.Field[any]) (err error) {
if err = tx.Commit(); nil != err {
t.error(err, "开始数据库事务出错", fields...)
}
return
}
func (t *Tx) commit(tx *xorm.Session, fields ...gox.Field[any]) {
if err := tx.Commit(); nil != err {
t.error(err, "提交数据库事务出错", fields...)
}
}
func (t *Tx) close(tx *xorm.Session, fields ...gox.Field[any]) {
if err := tx.Close(); nil != err {
t.error(err, "关闭数据库事务出错", fields...)
}
}
func (t *Tx) rollback(tx *xorm.Session, fields ...gox.Field[any]) {
if err := tx.Rollback(); nil != err {
t.error(err, "回退数据库事务出错", fields...)
}
}
func (t *Tx) error(err error, msg string, fields ...gox.Field[any]) {
fun, _, line, _ := runtime.Caller(1)
logFields := make([]gox.Field[any], 0, len(fields)+4)
logFields = append(logFields, field.New("fun", runtime.FuncForPC(fun).Name()))
logFields = append(logFields, field.New("line", line))
logFields = append(logFields, fields...)
logFields = append(logFields, field.Error(err))
t.logger.Error(msg, logFields...)
}