注意事项
Session,Engine避坑指南
Session
正确方法
//GetDbInstance里面缓存了所有mysql实例的连接对象,Engine是对于连接实例全局已经实现了单例,GetSession方法能正确的获取Engine创建的Session
session := torm.GetDbInstance("encourage", "writer").GetSession()
session.Begin()
...
session.Commit()
错误方法
//禁止将torm.DbBaseDao类型对象变成全局对象
var db torm.DbBaseDao
func dbdemo(){
//禁止私自创建DbBaseDao对象
db = new(torm.DbBaseDao)
//强制使用GetInstance方法获取mysql实例对象
reader := torm.GetDbInstance("default", "writer")
//此处将reader.Engine复制给全局db实例会让session全局化,session全局范围内共享
db.UpdateEngine(reader.Engine)
//这块获取的session已经是全局共享了
session := db.GetSession()
session.Begin()
//这里的数据库操作执行会出问题
...
session.Commit()
}
Engine
正确方法
//GetDbInstance里面缓存了所有mysql实例的连接对象,Engine是对于连接实例全局已经实现了单例
engine := torm.GetDbInstance("encourage", "writer").Engine
错误方法
//禁止将torm.DbBaseDao类型对象变成全局对象
var db torm.DbBaseDao
func dbdemo(){
//禁止私自创建DbBaseDao对象
db = new(torm.DbBaseDao)
//强制使用GetInstance方法获取mysql实例对象
reader := torm.GetDbInstance("default", "reader")
//此处将reader.Engine复制给全局db实例会让session全局化,session全局范围内共享
db.UpdateEngine(reader.Engine)
}
表结构体私有化
用自动代码生成工具(xorm)生成的表映射结构体,在使用的时候是并发不安全的,请不要当做共享变量
来使用,
正确的方式是作为私有变量
,即谁使用谁实例化
自动生产的表模型如下
package sqlFollowClass
import (
"github.com/tal-tech/torm"
)
type XesOfflineWarn struct {
Id int `xorm:"not null pk autoincr INT(10)"`
OfflineType int `xorm:"not null default 2 comment('离线类型 2不在线 3挂机') TINYINT(4)"`
TimeSec int `xorm:"not null default 2 comment('时间分钟') INT(11)"`
BizId int `xorm:"not null default 0 comment('业务ID') INT(11)"`
PlanId int `xorm:"not null default 0 comment('场次ID') index(plan_id_stu_id) INT(11)"`
ClassId int `xorm:"not null default 0 comment('班级ID') INT(11)"`
StuId int `xorm:"not null default 0 comment('学生ID') index(plan_id_stu_id) INT(11)"`
TeacherId int `xorm:"not null default 0 comment('辅导老师ID') INT(11)"`
CreateTime int64 `xorm:"not null default 0 comment('创建时间戳') BIGINT(20)"`
}
type XesOfflineWarnDao struct {
torm.DbBaseDao
}
func NewXesOfflineWarnDao(v ...interface{}) *XesOfflineWarnDao {
this := new(XesOfflineWarnDao)
if ins := torm.GetDbInstance("default", "writer"); ins != nil {
this.UpdateEngine(ins.Engine)
} else {
return nil
}
if len(v) != 0 {
this.UpdateEngine(v...)
}
return this
}
func (this *XesOfflineWarnDao) Get(mId torm.Param) (ret []XesOfflineWarn, err error) {
ret = make([]XesOfflineWarn, 0)
this.InitSession()
this.BuildQuery(mId, "id")
err = this.Session.Find(&ret)
return
}
服务层调用示例
//正确方式
for {
//每次循环,代表一个执行分支
dbins := sqlFollowClass.NewXesOfflineWarnDao()
dbins.Get(torm.Param(1))
}
//错误方式
dbins2 := sqlFollowClass.NewXesOfflineWarnDao()
for {
go func() {
dbins2.Get(torm.Param(1))
}()
go func() {
dbins2.Get(torm.Param(1))
}()
go func() {
dbins2.Get(torm.Param(1))
}()
}