XORM中管理多数据源须按业务边界隔离Engine实例:读写分离用EngineGroup,独立库用多个Engine;连接池参数需逐个配置;事务必须绑定单一Engine。

在XORM中管理多个数据源,核心是避免全局混用Engine实例导致事务混乱、连接泄漏或读写错库。必须按业务边界显式隔离Engine生命周期与用途,不能靠“手动切换”或共享指针应付。
明确区分主从/分库场景再选引擎类型
如果业务需要读写分离(如主库写、从库读),【必须使用EngineGroup】,它内置了策略路由(如Random、RoundRobin、Weighted等),能自动分发查询;如果只是多个独立数据库(如订单库、用户库、日志库),则应创建多个独立的Engine实例,各自维护连接池与事务上下文。
混用两种模式会导致路由失效或panic:EngineGroup不支持单库事务提交,而多个Engine共用同一事务对象会报错“transaction not started”。
多个独立Engine实例的初始化与命名规范
方法一:按业务域声明全局变量并集中初始化
在model包下定义清晰命名的Engine变量,例如:var UserEngine, OrderEngine, LogEngine *xorm.Engine。每个变量对应一个独立DSN,驱动名一致但数据库名不同。
方法二:封装为带名称的Engine工厂函数
用闭包返回带标识的Engine,避免全局污染:func NewUserEngine() (*xorm.Engine, error) { return xorm.NewEngine("mysql", userDSN) }。调用时直接获取,不暴露原始指针。
注意:每个Engine必须单独调用ShowSQL(true)和Ping(),否则日志开关和连通性检测只作用于最后一个赋值的实例。
连接池参数必须逐个独立配置
第一步:为每个Engine显式设置连接池上限
UserEngine.SetMaxOpenConns(50) → OrderEngine.SetMaxOpenConns(80) → LogEngine.SetMaxOpenConns(20)。订单库QPS高需更多并发连接,日志库写多读少可压低上限。
第二步:空闲连接数不可大于最大打开数
UserEngine.SetMaxIdleConns(10),若设为60会静默截断为50,造成空闲连接无法复用,频繁新建连接。
第三步:强制连接过期时间防止MySQL wait_timeout中断
UserEngine.SetConnMaxLifetime(30 * time.Minute)。缺少这步,长时间空闲后重用连接会触发invalid connection错误,且错误不抛出到上层,只静默失败。
事务必须绑定到具体Engine实例
方法一:使用Engine.Begin()启动事务
sess, err := UserEngine.NewSession() → err = sess.Begin() → 后续所有sess.Insert()、sess.Update()都走该会话,最终sess.Commit()或sess.Rollback()。
方法二:禁止跨Engine事务
不能在一个事务里同时操作UserEngine和OrderEngine,XORM不支持分布式事务。若需强一致性,改用Saga模式或消息表补偿。
这一步操作起来很简单,直接把事务逻辑限定在单个Engine的Session内就行。











