记在 Hyperf 中多库连接操作事务注意事项
业务场景中很多时候我们不止有一个数据库实例,这时候就需要配置多库连接。
当我们时候 Hyperf 来作为项目框架时,多库连接操作事务需要注意 database.php 中配置的每一个连接都是相互隔离的。
如果我们的 database.php 配置文件如下
return [
'default' => [
'database' => 'mysql1',
....忽略其他参数
],
'mysql1'=>[
'database' => 'mysql1',
....忽略其他参数
],
'mysql2'=>[
'database' => 'mysql2',
....忽略其他参数
],
];
可以看到默认库为 mysql1。
现在我们来创建三张表
class Test1 extends Model
{
protected $table = 'test1';
protected $connection = 'mysql1';
}
class Test2 extends Model
{
protected $table = 'test2';
protected $connection = 'mysql1';
}
class Test3 extends Model
{
protected $table = 'test3';
protected $connection = 'mysql2';
}
这时候如果是按照 Laravel 的习惯,我们在操作事务时只要是不跨实例的库,都无需指定数据库连接
//如果跨实例,则需要指定数据库连接
//Db::connection("mysql1")->beginTransaction();
//Db::connection("mysql2")->beginTransaction();
Db::beginTransaction();
try {
//mysql1数据库
DB::table("test1")->insert([
'code' => 1,
]);
//mysql2数据库
DB::table("test3")->insert([
'name' => 1
]);
Db::commit();
} catch(\Throwable $e) {
Db::rollback();
$this->error("失败了=".$e->getMessage());
}
在 Hyperf 中需要注意,上面我们说到的每个连接都是相互隔离的,所以我们在操作事务的时候如果模型中 connection 指定的不是 default,则在操作事务时候需要指定链接
Db::connection('mysql1')->beginTransaction();
try {
Db::table("test1")->insert([
'name' => 1,
]);
Db::table("test2")->insert([
'name' => 2
]);
Db::connection('mysql1')->commit();
} catch (\Throwable $e) {
Db::connection('mysql1')->rollback();
}
否则就会导致事务失效的情况
本作品采用《CC 协议》,转载必须注明作者和本文链接