thinkphp 5.0–5.1读写分离需配置deploy=>1启用,且依赖intransaction()和写操作标记强制主库,read_master=true仅在显式读取环境变量且slave为一维数组时生效;find/select等查询方法满足条件才走从库,query/execute及事务内操作始终走主库。

ThinkPHP 5.0–5.1 的读写分离不是“SQL 自动识别切换”,它靠配置 + 状态标记双控,配错一个环节就全走主库。
为什么设了 read_master => true 却没走从库?
TP5.0–5.1 的从库路由逻辑极简,只看两个运行时标记:
-
inTransaction()返回true→ 强制主库 - 上一条执行的 SQL 是写操作(内部靠
lastInsID或lastSql判断)→ 强制主库
只要任一为真,后续所有 find()、select()、get() 都不会走从库。常见踩坑场景:
- 刚执行过
insert(),紧接着查这条记录,加slave()也无效——写标记还在 -
Db::table()->where()->update()后立刻->select(),结果仍是主库 -
read_master写在.env里,但配置文件没用env('READ_MASTER', false)显式读取,实际未生效
slave 配置必须是一维扁平化数组
TP5.0–5.1 不支持二维 slave 数组,以下写法会静默失败或连错库:
'slave'=> [
['host'=>'s1'],
['host'=>'s2']
]
正确写法是扁平化的一维结构,用英文逗号分隔多个值:
'hostname'=>'192.168.1.10,192.168.1.11', 'username'=>'user1,user2', 'password'=>'pass1,pass2', 'hostport'=>'3306,3306', 'deploy'=> 1, 'rw_separate'=> true, 'read_master'=> true,
注意:deploy => 1 是启用分布式模式的前提,缺了它,rw_separate 和 read_master 全部无效。
哪些方法真正走从库?哪些不走?
只有显式调用查询类方法且满足路由条件时才可能走从库:
- 走从库:
find()、select()、get()、value()、column() - 不走从库:
query()和execute()默认走主库(无论 SQL 是 SELECT 还是 INSERT) - 关联查询(如
with())默认不触发从库路由,哪怕底层是 SELECT - 事务内所有操作强制主库,
startTrans()→commit()区间内无例外
想临时强制走主库读,可用 master(true),例如:Db::table('user')->master(true)->find(1)。
最易被忽略的是 deploy => 1 这个开关——它不像 rw_separate 那样直觉可见,但没它,整个读写分离逻辑根本不会初始化。另外,主从延迟下“写完立刻查”必须手动指定 master(true),框架不会帮你判断一致性需求。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











