/
routine-transation.go
99 lines (83 loc) · 2.76 KB
/
routine-transation.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
95
96
97
98
99
package transaction_manager
import (
"context"
"errors"
"strconv"
"sync"
"sync/atomic"
. "xorm.io/xorm"
)
var (
MapError = errors.New("error loaded session in the map")
)
var managerCont uint64 = 0
type routineTransactionManager struct {
id string
synchronizeSessionMap sync.Map
engine EngineInterface
}
func (tm *routineTransactionManager) DynamicSessionFunc() DynamicSession {
return func(...context.Context) (*Session, error) {
store, _ := tm.synchronizeSessionMap.LoadOrStore(tm.id+strconv.FormatUint(curGoroutineID(), 10), tm.engine.NewSession())
session, ok := store.(*Session)
if !ok {
return nil, MapError
}
return session, nil
}
}
func (tm *routineTransactionManager) Do(ctx context.Context, transactionFunc TransactionFunc, definition ...TransactionDefinition) error {
var result error
store, loaded := tm.synchronizeSessionMap.LoadOrStore(tm.id+strconv.FormatUint(curGoroutineID(), 10), tm.engine.NewSession())
session, ok := store.(*Session)
if !ok {
return MapError
}
//transaction is managed by the first called
if !loaded {
if err := session.Begin(); err != nil {
return err
}
defer func() {
// commit session if result is nil
if result == nil {
result = session.Commit()
}
if err := session.Close(); err != nil {
result = err
}
tm.synchronizeSessionMap.Delete(curGoroutineID())
}()
}
result = transactionFunc(ctx, session)
return result
}
func (tm *routineTransactionManager) IsInTransaction(ctx context.Context) bool {
_, ok := tm.synchronizeSessionMap.Load(tm.id + strconv.FormatUint(curGoroutineID(), 10))
return ok
}
func (tm *routineTransactionManager) Required(ctx context.Context, transactionFunc TransactionFunc) error {
panic("implement me")
}
func (tm *routineTransactionManager) Supports(ctx context.Context, transactionFunc TransactionFunc) error {
panic("implement me")
}
func (tm *routineTransactionManager) Mandatory(ctx context.Context, transactionFunc TransactionFunc) error {
panic("implement me")
}
func (tm *routineTransactionManager) RequiresNew(ctx context.Context, transactionFunc TransactionFunc) error {
panic("implement me")
}
func (tm *routineTransactionManager) NotSupported(ctx context.Context, transactionFunc TransactionFunc) error {
panic("implement me")
}
func (tm *routineTransactionManager) Never(ctx context.Context, transactionFunc TransactionFunc) error {
panic("implement me")
}
func (tm *routineTransactionManager) Nested(ctx context.Context, transactionFunc TransactionFunc) error {
panic("implement me")
}
// NewRoutineTransactionManager
func NewRoutineTransactionManager(engine EngineInterface) TransactionManager {
return &routineTransactionManager{id: strconv.FormatUint(atomic.AddUint64(&managerCont, 1), 10), engine: engine}
}