在tp6中直接赋值$this->connection无效,须在initialize()中注入预创建的db连接实例,关联查询需显式指定connection,禁用已移除的model::db(),事务操作必须严格绑定同一连接实例。

模型里直接改 $connection 属性没用
很多人以为在模型方法里写 $this->connection = 'mysql2' 就能切库,实际完全无效。因为 $connection 是静态属性,只在模型类首次加载时读取一次,后续赋值不会触发连接重建,也不会影响任何查询行为。
initialize() 中手动注入连接对象才生效
想让单次请求中模型走指定库,必须在 initialize() 方法里把运行时构造的连接实例挂到模型上。这个连接得提前准备好(比如从中间件挂载到 Request 或容器),不能临时 new 或靠配置名硬写。
- 确保中间件已解析租户 ID,并调用
Db::connect($config)创建连接,再存到$request->db或app('tenant.db') - 模型中重写
initialize():$this->connection = app('request')->db; - 注意:关联查询(
with())不会自动继承该连接,被关联模型仍按自己$connection走,需显式指定'connection' => 'xxx'在关联定义里
别用 Model::db(),那是 TP3 的遗留接口
ThinkPHP 6 已移除 Model::db() 方法。你在 TP6 模型里调用 $this->db(1, $config) 会报错 Call to undefined method。这个方法只存在于 TP3.2,且依赖全局配置键如 DB_CONFIG1,和 TP6 的配置结构不兼容。
- TP6 没有数字编号连接池机制,
db(1)这种写法无对应实现 - 试图复用 TP3 文档里的代码,会导致 Fatal error
- 如果项目从 TP3 升级上来,必须全部替换为
Db::connect()+ 显式对象调用,或重构为 Request 绑定模式
事务和连接复用必须严格绑定同一个实例
动态切换后最容易被忽略的是事务边界。一旦你在模型里用了 $this->connection = $db1,所有操作(包括 save()、delete()、startTrans())都必须基于这个 $db1 实例。跨连接开启事务会静默失败,或只在第一个连接提交而第二个丢弃。
- 不要在一个事务块里混用
$db1->startTrans()和$db2->commit() - 高频请求下避免每次
initialize()都调Db::connect(),应复用中间件创建好的实例 - 检查
show processlist,确认没有大量 Sleep 状态连接堆积——那说明连接没被复用或未正确关闭
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











