package base import ( "fmt" "github.com/druidcaesa/gotool" "sync" "ulink-admin/frame" "ulink-admin/frame/third_plugins/http" "xorm.io/xorm" ) var sessionMap sync.Map var userMap sync.Map const ( ADMIN = "admin" MEMBER = "member" ) type UserInfo struct { Id int64 Name string IsAdmin bool ComponyId int64 UserType string } func GetCurUser() *UserInfo { routineId := http.GetRoutineId() txv, ok := userMap.Load(routineId) if ok { return txv.(interface{}).(*UserInfo) } else { return nil } } func SetCurUser(user *UserInfo) { routineId := http.GetRoutineId() userMap.Store(routineId, user) } type SessionPlus struct { Session *xorm.Session //session IsTx bool //是否开启事务 Level int //事务层级 Id uint64 } func GetSession() *SessionPlus { //var transMap map[string]*xorm.Session var sessionPlus *SessionPlus //获取线程id routineId := http.GetRoutineId() txv, ok := sessionMap.Load(routineId) fmt.Printf("routineId:%d\n", routineId) //如果从根据当前线程ID从缓存中获取到了。 //否则则获取一个新的Session if ok { sessionPlus = txv.(interface{}).(*SessionPlus) //session = transMap["tx"] } else { sessionPlus = &SessionPlus{Session: SqlDB.NewSession(), IsTx: false, Id: routineId} sessionMap.Store(routineId, sessionPlus) } return sessionPlus } func Transaction(f func(session *xorm.Session)) { var err error sessionPlus := GetSession() if sessionPlus.IsTx == false { if err = sessionPlus.Session.Begin(); err != nil { gotool.Logs.ErrorLog().Println("session begin failed, err msg: %s", err.Error()) frame.Throw(frame.BUSINESS_CODE, "session begin failed") } else { sessionPlus.IsTx = true sessionPlus.Level = 1 } } else { sessionPlus.Level = sessionPlus.Level + 1 } defer func() { //抛出异常,开启事务,并且事务层级等于1 //支持镶套事务处理 if sessionPlus.Level <= 1 && sessionPlus.IsTx { if r := recover(); r != nil { gotool.Logs.ErrorLog().Println("异常%v", r) if err := sessionPlus.Session.Rollback(); err != nil { gotool.Logs.ErrorLog().Println("session rollback failed, err msg: %s", err.Error()) } sessionPlus.IsTx = false sessionPlus.Session.Close() //Clean() frame.Throw(frame.SQL_CODE, fmt.Sprintf("数据库错误%v", r)) } else if err = sessionPlus.Session.Commit(); err != nil { gotool.Logs.ErrorLog().Println("session commit failed, err msg: %s", err.Error()) } sessionPlus.IsTx = false sessionPlus.Session.Close() //Clean() } if sessionPlus.Level > 1 && sessionPlus.IsTx { sessionPlus.Level = sessionPlus.Level - 1 if r := recover(); r != nil { frame.Throw(100, "镶嵌事务错误") } } }() f(sessionPlus.Session) } // Clean 关闭Session和根据进程ID清理缓存,以便GC回收 func Clean() { sessionMap.Delete(http.GetRoutineId()) userMap.Delete(http.GetRoutineId()) }