github.com/artisanhe/tools@v1.0.1-0.20210607022958-19a8fef2eb04/sqlx/task.go (about) 1 package sqlx 2 3 import ( 4 "fmt" 5 "runtime/debug" 6 7 "github.com/sirupsen/logrus" 8 ) 9 10 type Task func(db *DB) error 11 12 func (task Task) Run(db *DB) (err error) { 13 defer func() { 14 if e := recover(); e != nil { 15 err = fmt.Errorf("panic: %s; calltrace:%s", fmt.Sprint(e), string(debug.Stack())) 16 } 17 }() 18 return task(db) 19 } 20 21 func NewTasks(db *DB) *Tasks { 22 return &Tasks{ 23 db: db, 24 } 25 } 26 27 type Tasks struct { 28 db *DB 29 tasks []Task 30 } 31 32 func (tasks Tasks) With(task ...Task) *Tasks { 33 tasks.tasks = append(tasks.tasks, task...) 34 return &tasks 35 } 36 37 func (tasks *Tasks) Do() (err error) { 38 if len(tasks.tasks) == 0 { 39 return nil 40 } 41 42 db := tasks.db 43 inTxScope := false 44 45 if !db.IsTx() { 46 db, err = db.Begin() 47 if err != nil { 48 return err 49 } 50 inTxScope = true 51 } 52 53 for _, task := range tasks.tasks { 54 if runErr := task.Run(db); runErr != nil { 55 if inTxScope { 56 // err will bubble up,just handle and rollback in outermost layer 57 logrus.Errorf("SQL FAILED: %s", runErr.Error()) 58 if rollBackErr := db.Rollback(); rollBackErr != nil { 59 logrus.Errorf("ROLLBACK FAILED: %s", rollBackErr.Error()) 60 err = rollBackErr 61 return 62 } 63 } 64 return runErr 65 } 66 } 67 68 if inTxScope { 69 if commitErr := db.Commit(); commitErr != nil { 70 logrus.Errorf("TRANSACTION COMMIT FAILED: %s", commitErr.Error()) 71 return commitErr 72 } 73 } 74 75 return nil 76 }