```
~~~
<?php
namespace app\common\service;
use think\Exception;
class RedisLock {
/**
* 單據鎖redis key模板
*/
const REDIS_LOCK_KEY_TEMPLATE = 'order_lock_%s';
/**
* 單據鎖默認超時時間(秒)
*/
const REDIS_LOCK_DEFAULT_EXPIRE_TIME = 8;
/**
* Redis配置:IP
*/
const REDIS_CONFIG_HOST = '127.0.0.1';
/**
* Redis配置:端口
*/
const REDIS_CONFIG_PORT = 6379;
/**
* 加鎖key
*/
const REDIS_LOCK_UNIQUE_ID_KEY = 'lock_unique_id';
/**
* @param $intOrderId
* @param int $intExpireTime
* @return bool|int
* @throws Exception
* @describe: redis 加鎖
*/
public static function lock($intOrderId, $intExpireTime = self::REDIS_LOCK_DEFAULT_EXPIRE_TIME)
{
//參數校驗
if (empty($intOrderId) || $intExpireTime <= 0) {
return false;
}
//獲取Redis連接
$objRedisConn = self::getRedisConn();
//生成唯一鎖ID,解鎖需持有此ID
$intUniqueLockId = self::generateUniqueLockId();
//根據板,結合單據ID,生成唯一Redis key(一般來說,單據ID在業務中系統中唯一的)
$strKey = sprintf(self::REDIS_LOCK_KEY_TEMPLATE, $intOrderId);
//加鎖(通過Redis setnx指令實現,從Redis 2.6.12開始,通過set指令可選參數也可以實現setnx,同時可原子化地設置超時時間)
$bolRes = $objRedisConn->set($strKey, $intUniqueLockId, ['nx', 'ex'=>$intExpireTime]);
//加鎖成功返回鎖ID,加鎖失敗返回false
return $bolRes ? $intUniqueLockId : $bolRes;
}
/**
* @param $intOrderId
* @param $intLockId
* @return bool
* @throws Exception
* @describe:redis 解鎖
*/
public static function unlock($intOrderId, $intLockId)
{
//參數校驗
if (empty($intOrderId) || empty($intLockId)) {
return false;
}
//獲取Redis連接
$objRedisConn = self::getRedisConn();
//生成Redis key
$strKey = sprintf(self::REDIS_LOCK_KEY_TEMPLATE, $intOrderId);
//監聽Redis key防止在【比對lock id】與【解鎖事務執行過程中】被修改或刪除,提交事務后會自動取消監控,其他情況需手動解除監控
$objRedisConn->watch($strKey);
if ($intLockId == $objRedisConn->get($strKey)) {
$objRedisConn->multi()->del($strKey)->exec();
return true;
}
$objRedisConn->unwatch();
return false;
}
/**
* @param string $strIp
* @param int $intPort
* @return \Redis
* @throws Exception
* @describe:獲取Redis連接(簡易版本,可用單例實現)
*/
public static function getRedisConn($strIp = self::REDIS_CONFIG_HOST, $intPort = self::REDIS_CONFIG_PORT)
{
try {
if (!extension_loaded('redis')) {
throw new \BadFunctionCallException('not support: redis');
}
$objRedis = new \Redis();
$objRedis->connect($strIp, $intPort);
return $objRedis;
}catch (Exception $exception){
throw new Exception($exception->getMessage());
}
}
/**
* @return int
* @throws Exception
* @describe:生成鎖唯一ID(通過Redis incr指令實現簡易版本,可結合日期、時間戳、取余、字符串填充、隨機數等函數,生成指定位數唯一ID)
*/
public static function generateUniqueLockId()
{
return self::getRedisConn()->incr(self::REDIS_LOCK_UNIQUE_ID_KEY);
}
}
~~~
```
- 空白目錄
- thinkphp5
- tools-常用類庫
- redis類庫
- Excel類庫
- File文件操作類庫
- Http請求類庫
- Maile郵件發送
- Hooks行為鉤子
- 七牛云
- 隨機數和字符串生成
- 字符串處理
- 時間類處理
- tree型轉換
- 工具類庫
- 文件打包下載
- 常用功能
- 文件上傳
- php生成word文檔
- elasticsearch 基本搜索
- 使用jwt開發API接口
- 安裝模及搭建
- ApiCheck.php
- ApiCheckLogin.php
- common.php
- Login.php
- Comment.php
- 漢字轉拼音
- 安裝使用
- Pinyin類
- elasticsearch操作
- 常用方法
- 數據源生成layui-select
- 獲取自定義配置項
- 百度編輯器
- 格式化文件大小
- 多語言設置
- hook監聽
- 域名綁定到模塊
- thinkphp6
- 文件上傳
- tp5totp6
- 創建路徑
- 獲取類所有方法
- password_hash加密驗證
- 生成 qrcode
- 郵件發送
- 獲取QQ信息
- GoogleAuthenticator
- redis限流
- redis 加鎖
- 百度翻譯
- QueryList爬取數據
- 獲取時間類
- 命令
- Git常用命令
- easyswoole
- pix_qrcode
- 驗證 cpf,cnpj
- php常用方法
- 日志
- 卡通頭像
- 兩位小數
- 圖片轉base64
- auth加密解密
- phpoffice/phpspreadsheet導入導出
- fastadmin
- 樹結構
- 單選框
- 復選框
- 二級搜索
- select選擇框
- selectpage選中回調事件
- 標簽添加
- 修改where條件
- 表格列表中添加input框
- selectpage事件
- fieldlist
- js操作
- test_js
- 多表格
- template模板