记在 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 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!