必须显式创建EngineGroup实现读写分离,否则SQL全发往同一库;需按主从顺序配置DSN,Ping任一从库失败会导致读请求静默回退至主库;事务内所有操作强制走主库以保障一致性。

要在Go项目中用XORM实现读写分离,必须显式创建EngineGroup而非单个Engine实例,否则所有SQL都会发往同一数据库,根本无法触发主从分流逻辑。
初始化EngineGroup连接池
第一步:分别准备主库和从库的DSN字符串,确保主库地址写在数组第一个位置,XORM默认将首个连接作为master节点;从库地址可多个,按顺序轮询分发读请求。
第二步:调用xorm.NewEngineGroup()传入数据库类型和DSN切片,例如 PostgreSQL 场景下:eg, err := xorm.NewEngineGroup("postgres", []string{"master-dsn", "slave1-dsn", "slave2-dsn"})。
第三步:立即对EngineGroup执行Ping操作验证连通性,【若任一从库无法Ping通,XORM不会报错但后续读请求会静默 fallback 到主库,导致主库压力陡增】。
区分读写操作的底层机制
方法一:直接调用EngineGroup方法——Insert/Update/Delete/Exec等写操作自动路由到master;Query/Find/Get等读操作按负载策略(默认轮询)分发至某个slave。
方法二:使用Session控制作用域——session := eg.NewSession()后,在该session内执行的写操作走master,读操作走slave;但【禁止在同一个session中混用读写且不加事务】,否则可能因slave延迟导致读到旧数据。
方法三:强制指定节点——通过eg.Master().Query()或eg.Slave().Insert()绕过默认路由,仅用于调试或特殊场景,生产环境慎用。
事务中的读写一致性保障
事务必须全部在master上执行,这是硬性约束。XORM检测到session.StartTrans()后,自动禁用slave路由,后续所有操作(含SELECT)都发往master。
这一步不可跳过:开启事务前务必确认master连接可用,否则session.Begin()失败会导致整个事务流程中断。
事务提交或回滚后,session自动恢复读写分离行为,无需手动切换。











