業務場景中很多時候我們不止有一個資料庫例項,這時候就需要配置多庫連線。
當我們時候 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 協議》,轉載必須註明作者和本文連結