[奇技Y巧]解決程式快取鎖命名困難,命名衝突問題

Colorado發表於2021-07-02

平時加鎖總是奔波於命名,害怕命名衝突,不規範等問題,於是使用debug_backtrace函式通過呼叫鏈搞了一搞,通過file,class,function來確定一個鎖的位置,從而解決命名衝突,不規範等問題。(迎噴共近)

區域性鎖

對一段程式進行加鎖,保證該局域環境內或跨程式原子性,如傳送簡訊

public function sendSms(string $phone)
{
    if (! setnxLock($phone, 10)) return false;
    /**
     * 處理邏輯
     */
    delLock($phone);

    return true;
}

全域性鎖

如一個訂單多個地方都在處理,但只能單一處生效

public function handleOrder(string $order_no)
{
    if (! setnxLock($order_no, 10, true)) return false;
    /**
     * 處理邏輯
     */
    delLock($order_no, true);

    return true;
}

獲取快取鎖key

string getLockKey($key, true);

整理彙總

方法放在全域性方法中,方便全域性呼叫

<?php

use App\Constants\CacheKey;

if (! function_exists('setnxLock')) {
    /**
     * 設定快取鎖
     *
     * @param mixed $key     鎖鍵
     * @param int   $ttl     過期時間
     * @param bool  $global  是否全域性鎖
     *
     * @return bool
     */
    function setnxLock($key, int $ttl = 5, bool $global = false): bool
    {
        $lock_key = getLockKey($key, $global);

        return redis()->setnx($lock_key, 1) && redis()->expire($lock_key, $ttl);
    }
}

if (! function_exists('delLock')) {
    /**
     * 刪除快取鎖
     *
     * @param mixed $key     鎖鍵
     * @param bool  $global  是否全域性鎖
     *
     * @return bool
     */
    function delLock($key, bool $global = false): bool
    {
        $lock_key = getLockKey($key, $global);

        return redis()->del($lock_key);
    }
}

if (! function_exists('getLockKey')) {
    /**
     * 獲取快取鎖
     *
     * @param mixed $key     鎖鍵
     * @param bool  $global  是否全域性鎖
     *
     * @return string
     */
    function getLockKey($key, bool $global = false): string
    {
        if ($global) return CacheKey::GLOBAL_LOCK_CACHE_KEY . $key;

        return CacheKey::COMMON_LOCK_CACHE_KEY . md5(implode('', lockBacktrace())) . ':' . $key;
    }
}

if (! function_exists('lockBacktrace')) {
    /**
     * 獲取呼叫位置
     * 
     * @return array
     */
    function lockBacktrace(): array
    {
        $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 5)[4];
        $file = $backtrace['file'] ?? '';
        $class = $backtrace['class'] ?? '';
        $function = $backtrace['function'] ?? '';

        return compact('file', 'class', 'function');
    }
}

快取key管理類

class CacheKey extends AbstractConstants
{
    // 系統配置快取
    const SYSTEM_CONFIG_CACHE_KEY = 'hash:system_config_cache';
    // 全域性快取鎖
    const GLOBAL_LOCK_CACHE_KEY = 'string:global_lock:';
    // 普通快取鎖
    const COMMON_LOCK_CACHE_KEY = 'string:common_lock:';
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章