laravel框架下redis連接共享及select方法的影響
在Laravel框架中使用redis時,開發者可能會遇到一個問題:通過配置文件獲取的Redis連接,在使用select方法切換數據庫后,會影響到之前獲取的相同連接。本文將分析此問題并提供解決方案。
問題描述:假設代碼通過Redis::connection(‘config1’)獲取名為’config1’的Redis連接,其配置如下:
'config1' => [ 'host' => 'xx', 'password' => 'xx', 'port' => 'xx', 'database' => 2 ]
分別獲取兩次’config1’連接,并在其中一個連接上執行select(3)切換到數據庫3:
$a = Redis::connection('config1'); $b = Redis::connection('config1'); $b->select(3); $a->set('test1', 1); // 'test1'寫入數據庫3,而非預期數據庫2
$a->set(‘test1’, 1)的結果令人意外,因為預期數據應寫入數據庫2。這是因為Laravel框架的Redis連接管理機制導致$a和$b實際上引用的是同一個Redis連接對象。
Laravel框架的IlluminateSupportFacadesRedis facade 通過getFacadeAccessor方法返回redis,而redis是由IlluminateRedisRedisManager實現的。IlluminateRedisRedisManager的connection方法會在首次解析后緩存連接,后續調用會直接返回相同的Redis實例。
因此,要避免此問題,不能多次調用Redis::connection()來獲取獨立連接。解決方案是使用Laravel的resolve方法創建新的連接實例:
$a = app('redis')->connection('config1'); $b = app('redis')->connection('config1'); $b->select(3); $a->set('test1', 1); // 'test1'現在將寫入數據庫2
使用app(‘redis’)->connection(‘config1’)每次都會創建一個新的連接實例,從而避免共享同一個底層Redis連接的問題,確保每個連接擁有獨立的數據庫選擇。 這解決了select方法影響其他連接的問題。