Hyperf多数据库连接需显式配置独立连接池并绑定协程上下文:每个连接名唯一、pool参数须单独设置,运行时通过Db::connection()或模型$connection属性切换,事务必须用协程安全的Db::connection()->transaction(),模型实例应以transient方式注入,避免静态缓存导致协程污染。

Hyperf 的 Eloquent ORM 支持多数据库连接,但调用方式和生命周期管理与 Laravel 有本质区别——不是“写法相似就能复用”,而是必须按协程安全原则显式控制连接归属和模型实例作用域。
多连接配置要明确命名并隔离池参数
在 config/autoload/databases.php 中定义多个连接时,每个连接需独立配置 pool 参数,避免共用连接池导致资源争抢或超时连锁反应:
-
每个连接名必须唯一,如
'default'、'log_db'、'report_db',不能重名 -
pool 配置不可省略或共享,尤其
max_connections和wait_timeout应按业务负载单独设置 - MySQL 和 PostgreSQL 等不同驱动的连接,必须分开配置 host、port、database,不能混用
运行时切换连接必须绑定到当前协程上下文
所有数据库操作都应通过 Db::connection('xxx') 或模型指定 $connection 属性来显式声明连接,且该调用自动绑定当前协程:
- 查询构造器:
Db::connection('log_db')->table('logs')->where('level', 'error')->get() - Eloquent 模型:在类中声明
protected $connection = 'report_db';,该模型后续所有操作均走此连接 - 事务必须用
Db::connection('xxx')->transaction(...),静态DB::transaction()不协程安全
模型实例化必须声明生命周期策略
Hyperf 模型默认是常驻内存的单例,直接 new 或静态调用(如 User::find(1))会导致跨协程数据污染。正确做法是:
- 95% 场景下,模型应作为 transient 服务注入:
private User $user;+@Inject(transient=true) - 禁止在模型内使用
static $cache = []或手动赋值$this->connection,协程切换后连接可能已失效 - 若需预加载关联,必须在当前连接上下文中执行:
Db::connection('log_db')->table('logs')->with('user')->get()
事务与连接释放必须显式闭环
Hyperf 不像 Laravel 依赖请求结束自动清理,事务未提交或连接未释放会持续占用池资源:
- 事务块内发生异常时,
Db::connection('xxx')->transaction()会自动 rollback,无需手写 try/catch - 避免裸写
beginTransaction()/commit(),这些静态方法不绑定协程,极易错乱 - 长耗时查询或批量操作后,建议主动释放连接:
Db::connection('xxx')->reconnect()或等待空闲回收(由max_idle_time控制)


















