PHP 實現簡單阻塞分散式鎖

Dragonbuf發表於2018-09-14

最近看了很多分散式鎖的實現,但是對於簡單業務來說,太過於複雜。現在介紹一個簡單的、基於 mysql 實現的。這種實現方式對於 php-fpm 的來說十分方便,因為不用考慮 程式崩潰後鎖的釋放問題,程式崩潰後 鎖 回自動釋放。

具體實現

這裡主要是借用 mysql 的 for update 語法。假設有A B 兩臺伺服器連線同一個資料庫。
首先 A 伺服器進行此操作:

begin;
select * from nlock where id = 1 for update

此時 B 伺服器進行此操作

begin
select * from nlock where id = 1 for update

此時, A 伺服器 尚未提交事務,則 B 需要等待 A 伺服器提交事務後,才可以獲得鎖。
這樣就是一個簡單的分散式鎖。

這裡有個需要注意的地方:當 B 獲得鎖後,需要對自己所需資源的狀態進行重新判斷,因為你獲得鎖以後, 可能 A 對資源狀態進行了改變。

Demo:

function getLock($id)
{

    begin();

    try {
        $sql = "select id from `nlock` where id = " . $id . " for update";
        return DB($sql)->execute();
    } catch (Exception $e) {
        rollBack();
        throw $e;
    }
}

function releaseLock()
{
    commit();
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章