Laravel で↓のように read/write
の接続先を設定したとき。
<?php
return [
'default' => env('DB_CONNECTION', 'mysql'),
'connections' => [
'mysql' => [
'driver' => 'mysql',
'read' => [
'host' => env('DB_SLAVE_HOST', '127.0.0.1'),
'port' => env('DB_SLAVE_PORT', '3306'),
],
'write' => [
'host' => env('DB_MASTER_HOST', '127.0.0.1'),
'port' => env('DB_MASTER_PORT', '3306'),
],
'database' => env('DB_DATABASE', 'test'),
'username' => env('DB_USERNAME', 'ore'),
'password' => env('DB_PASSWORD', 'are'),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8',
'collation' => 'utf8_bin',
'prefix' => '',
'strict' => false,
'engine' => null,
],
],
];
意図的にマスターで SELECT したりスレーブでトランザクションする方法。
Illuminate の Connection オブジェクトは2つの PDO インスタンスを持っていて、
実行するクエリによってどちらを使うかが選択されているようなのですが、
トランザクションを開始しているときは常にマスターの方が使われます。
なので明示的にマスターを指定するのは単にトランザクションに入れればOKです。
DB::select('select user_name from users'); // -> SLAVE
$user = User::find('admin'); // -> SLAVE
$user->user_name = 'oreore';
$user->save(); // -> MASTER
DB::transaction(function() { // -> MASTER
DB::select('select user_name from users'); // -> MASTER
$user = User::find('admin'); // -> MASTER
$user->user_name = 'areare';
$user->save(); // -> MASTER
});
普通にトランザクションを開始するとその中ではマスターを見に行ってしまうので、読み取り一貫性のためにスレーブでトランザクションを開始したいときはあんまり綺麗な方法はなさそうです。
try {
DB::getReadPdo()->beginTransaction(); // -> SLAVE
$user = User::find('admin'); // -> SLAVE
} finally {
DB::getReadPdo()->rollBack(); // -> SLAVE