注意事项

Session,Engine避坑指南

Session

正确方法

  1. //GetDbInstance里面缓存了所有mysql实例的连接对象,Engine是对于连接实例全局已经实现了单例,GetSession方法能正确的获取Engine创建的Session
  2. session := torm.GetDbInstance("encourage", "writer").GetSession()
  3. session.Begin()
  4. ...
  5. session.Commit()

错误方法

  1. //禁止将torm.DbBaseDao类型对象变成全局对象
  2. var db torm.DbBaseDao
  3. func dbdemo(){
  4. //禁止私自创建DbBaseDao对象
  5. db = new(torm.DbBaseDao)
  6. //强制使用GetInstance方法获取mysql实例对象
  7. reader := torm.GetDbInstance("default", "writer")
  8. //此处将reader.Engine复制给全局db实例会让session全局化,session全局范围内共享
  9. db.UpdateEngine(reader.Engine)
  10. //这块获取的session已经是全局共享了
  11. session := db.GetSession()
  12. session.Begin()
  13. //这里的数据库操作执行会出问题
  14. ...
  15. session.Commit()
  16. }

Engine

正确方法

  1. //GetDbInstance里面缓存了所有mysql实例的连接对象,Engine是对于连接实例全局已经实现了单例
  2. engine := torm.GetDbInstance("encourage", "writer").Engine

错误方法

  1. //禁止将torm.DbBaseDao类型对象变成全局对象
  2. var db torm.DbBaseDao
  3. func dbdemo(){
  4. //禁止私自创建DbBaseDao对象
  5. db = new(torm.DbBaseDao)
  6. //强制使用GetInstance方法获取mysql实例对象
  7. reader := torm.GetDbInstance("default", "reader")
  8. //此处将reader.Engine复制给全局db实例会让session全局化,session全局范围内共享
  9. db.UpdateEngine(reader.Engine)
  10. }

表结构体私有化

用自动代码生成工具(xorm)生成的表映射结构体,在使用的时候是并发不安全的,请不要当做共享变量来使用,
正确的方式是作为私有变量,即谁使用谁实例化

自动生产的表模型如下

  1. package sqlFollowClass
  2. import (
  3. "github.com/tal-tech/torm"
  4. )
  5. type XesOfflineWarn struct {
  6. Id int `xorm:"not null pk autoincr INT(10)"`
  7. OfflineType int `xorm:"not null default 2 comment('离线类型 2不在线 3挂机') TINYINT(4)"`
  8. TimeSec int `xorm:"not null default 2 comment('时间分钟') INT(11)"`
  9. BizId int `xorm:"not null default 0 comment('业务ID') INT(11)"`
  10. PlanId int `xorm:"not null default 0 comment('场次ID') index(plan_id_stu_id) INT(11)"`
  11. ClassId int `xorm:"not null default 0 comment('班级ID') INT(11)"`
  12. StuId int `xorm:"not null default 0 comment('学生ID') index(plan_id_stu_id) INT(11)"`
  13. TeacherId int `xorm:"not null default 0 comment('辅导老师ID') INT(11)"`
  14. CreateTime int64 `xorm:"not null default 0 comment('创建时间戳') BIGINT(20)"`
  15. }
  16. type XesOfflineWarnDao struct {
  17. torm.DbBaseDao
  18. }
  19. func NewXesOfflineWarnDao(v ...interface{}) *XesOfflineWarnDao {
  20. this := new(XesOfflineWarnDao)
  21. if ins := torm.GetDbInstance("default", "writer"); ins != nil {
  22. this.UpdateEngine(ins.Engine)
  23. } else {
  24. return nil
  25. }
  26. if len(v) != 0 {
  27. this.UpdateEngine(v...)
  28. }
  29. return this
  30. }
  31. func (this *XesOfflineWarnDao) Get(mId torm.Param) (ret []XesOfflineWarn, err error) {
  32. ret = make([]XesOfflineWarn, 0)
  33. this.InitSession()
  34. this.BuildQuery(mId, "id")
  35. err = this.Session.Find(&ret)
  36. return
  37. }

服务层调用示例

  1. //正确方式
  2. for {
  3. //每次循环,代表一个执行分支
  4. dbins := sqlFollowClass.NewXesOfflineWarnDao()
  5. dbins.Get(torm.Param(1))
  6. }
  7. //错误方式
  8. dbins2 := sqlFollowClass.NewXesOfflineWarnDao()
  9. for {
  10. go func() {
  11. dbins2.Get(torm.Param(1))
  12. }()
  13. go func() {
  14. dbins2.Get(torm.Param(1))
  15. }()
  16. go func() {
  17. dbins2.Get(torm.Param(1))
  18. }()
  19. }