亚洲综合原千岁中文字幕_国产精品99久久久久久久vr_无码人妻aⅴ一区二区三区浪潮_成人h动漫精品一区二区三

主頁 > 知識庫 > PHP實現Redis單據鎖以及防止并發重復寫入

PHP實現Redis單據鎖以及防止并發重復寫入

熱門標簽:長沙做地圖標注公司 福建銀行智能外呼系統價格 寧波外呼營銷系統 房產中介用的是什么外呼系統 遼寧ai電銷機器人價格 四川保險智能外呼系統供應商 電話機器人銷售主要負責什么 上海做外呼線路的通信公司 地圖標注專員怎么樣

一、寫在前面:

在整個供應鏈系統中,會有很多種單據(采購單、入庫單、到貨單、運單等等),在涉及寫單據數據的接口時(增刪改操作),即使前端做了相關限制,還是有可能因為網絡或異常操作產生并發重復調用的情況,導致對相同單據做相同的處理;

為了防止這種情況對系統造成異常影響,我們通過Redis實現了一個簡單的單據鎖,每個請求需先獲取鎖才能執行業務邏輯,執行結束后才會釋放鎖;保證了同一單據的并發重復操作請求只有一個請求可以獲取到鎖(依賴Redis的單線程),是一種悲觀鎖的設計;

注:Redis鎖在我們的系統中一般只用于解決并發重復請求的情況,對于非并發的的重復請求一般會去數據庫或日志校驗數據的狀態,兩種機制結合起來才能保證整個鏈路的可靠。

二、加鎖機制:

主要依賴Redis setnx指令實現:

但使用setnx有一個問題,即setnx指令不支持設置過期時間,需要使用expire指令另行為key設置超時時間,這樣整個加鎖操作就不是一個原子性操作,有可能存在setnx加鎖成功,但因程序異常退出導致未成功設置超時時間,在不及時解鎖的情況下,有可能會導致死鎖(即使業務場景中不會出現死鎖,無用的key一直常駐內存也不是很好的設計);

這種情況可以使用Redis事務解決,把setnx與expire兩條指令作為一個原子性操作執行,但這樣做相對而言會比較麻煩,好在Redis 2.6.12之后版本,Redis set指令支持了nx、ex模式,并支持原子化地設置過期時間:

三、加鎖實現(完整測試代碼會貼在最后):

 /**
  * 加單據鎖
  * @param int $intOrderId 單據ID
  * @param int $intExpireTime 鎖過期時間(秒)
  * @return bool|int 加鎖成功返回唯一鎖ID,加鎖失敗返回false
  */
 public static function addLock($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;
 }

四、解鎖機制:

解鎖即比對加鎖時的唯一lock id,如果比對成功,則刪除key;需要注意的是,解鎖整個過程中同樣需要保證原子性,這里依賴redis的watch與事務實現;

WATCH命令可以監控一個或多個鍵,一旦其中有一個鍵被修改(或刪除),之后的事務就不會執行。監控一直持續到EXEC命令(事務中的命令是在EXEC之后才執行的,所以在MULTI命令后可以修改WATCH監控的鍵值)

五、解鎖實現(完整測試代碼會貼在最后):

/**
  * 解單據鎖
  * @param int $intOrderId 單據ID
  * @param int $intLockId 鎖唯一ID
  * @return bool
  */
 public static function releaseLock($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;
 }

六、附整體測試代碼(此代碼僅為簡易版本)

?php

/**
 * Class Lock_Service 單據鎖服務
 */
class Lock_Service
{
 /**
  * 單據鎖redis key模板
  */
 const REDIS_LOCK_KEY_TEMPLATE = 'order_lock_%s';

 /**
  * 單據鎖默認超時時間(秒)
  */
 const REDIS_LOCK_DEFAULT_EXPIRE_TIME = 86400;

 /**
  * 加單據鎖
  * @param int $intOrderId 單據ID
  * @param int $intExpireTime 鎖過期時間(秒)
  * @return bool|int 加鎖成功返回唯一鎖ID,加鎖失敗返回false
  */
 public static function addLock($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 int $intOrderId 單據ID
  * @param int $intLockId 鎖唯一ID
  * @return bool
  */
 public static function releaseLock($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;
 }

 /**
  * Redis配置:IP
  */
 const REDIS_CONFIG_HOST = '127.0.0.1';

 /**
  * Redis配置:端口
  */
 const REDIS_CONFIG_PORT = 6379;

 /**
  * 獲取Redis連接(簡易版本,可用單例實現)
  * @param string $strIp IP
  * @param int $intPort 端口
  * @return object Redis連接
  */
 public static function getRedisConn($strIp = self::REDIS_CONFIG_HOST, $intPort = self::REDIS_CONFIG_PORT)
 {
  $objRedis = new Redis();
  $objRedis->connect($strIp, $intPort);
  return $objRedis;
 }

 /**
  * 用于生成唯一的鎖ID的redis key
  */
 const REDIS_LOCK_UNIQUE_ID_KEY = 'lock_unique_id';

 /**
  * 生成鎖唯一ID(通過Redis incr指令實現簡易版本,可結合日期、時間戳、取余、字符串填充、隨機數等函數,生成指定位數唯一ID)
  * @return mixed
  */
 public static function generateUniqueLockId()
 {
  return self::getRedisConn()->incr(self::REDIS_LOCK_UNIQUE_ID_KEY);
 }
}

//test
$res1 = Lock_Service::addLock('666666');
var_dump($res1);//返回lock id,加鎖成功
$res2 = Lock_Service::addLock('666666');
var_dump($res2);//false,加鎖失敗
$res3 = Lock_Service::releaseLock('666666', $res1);
var_dump($res3);//true,解鎖成功
$res4 = Lock_Service::releaseLock('666666', $res1);
var_dump($res4);//false,解鎖失敗

以上就是本次給大家整理的全部內容,感謝大家對腳本之家的支持。

您可能感興趣的文章:
  • 詳解利用redis + lua解決搶紅包高并發的問題
  • Nginx+Lua+Redis構建高并發Web應用
  • Redis實現高并發計數器
  • 如何利用Redis鎖解決高并發問題詳解
  • Redis瞬時高并發秒殺方案總結
  • jedispool連redis高并發卡死的問題
  • 使用lua+redis解決發多張券的并發問題

標簽:延安 宜春 深圳 常德 佛山 宿遷 工商登記 澳門

巨人網絡通訊聲明:本文標題《PHP實現Redis單據鎖以及防止并發重復寫入》,本文關鍵詞  PHP,實現,Redis,單據,鎖,以及,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《PHP實現Redis單據鎖以及防止并發重復寫入》相關的同類信息!
  • 本頁收集關于PHP實現Redis單據鎖以及防止并發重復寫入的相關信息資訊供網民參考!
  • 推薦文章
    99久久精品国产高清一区二区| 毛片高清| 韩国三级香港三级日本三级| 国产成a人片在线观看视频| 久久99这里只有精品国产| a级黄色毛片免费播放视频| 国产不卡福利| 精品国产亚洲人成在线| 亚洲第一色在线| 国产a视频| 天天色成人网| 日韩av成人| 国产成人精品综合在线| 欧美国产日韩在线| 青青久久精品| 九九九国产| 四虎久久精品国产| 日韩中文字幕一区| 精品视频在线观看一区二区三区| 一级女性全黄生活片免费| 欧美电影免费看大全| 国产不卡福利| 毛片高清| 日韩在线观看视频免费| 在线观看导航| 99久久精品国产免费| 一级女性全黄久久生活片| 日韩中文字幕在线亚洲一区| 久久精品免视看国产明星| 97视频免费在线观看| 国产91丝袜在线播放0| 黄视频网站在线免费观看| 国产美女在线观看| 亚洲天堂一区二区三区四区| 美国一区二区三区| 精品视频免费在线| 好男人天堂网 久久精品国产这里是免费 国产精品成人一区二区 男人天堂网2021 男人的天堂在线观看 丁香六月综合激情 | 国产视频网站在线观看| 国产一区二区高清视频| 91麻豆tv| 你懂的在线观看视频| 999久久66久6只有精品| 日韩在线观看免费完整版视频| 好男人天堂网 久久精品国产这里是免费 国产精品成人一区二区 男人天堂网2021 男人的天堂在线观看 丁香六月综合激情 | 国产网站免费视频| 久久国产精品自线拍免费| 久久福利影视| 成人免费观看视频| 精品国产一级毛片| 欧美激情一区二区三区在线| 国产视频一区在线| 日韩专区一区| 九九免费高清在线观看视频| 日韩一级黄色| 国产一区二区精品久久91| 可以免费看毛片的网站| 国产一区免费在线观看| 欧美一级视频免费观看| 九九热国产视频| 日本伦理片网站| 国产美女在线一区二区三区| 久久成人综合网| 欧美一级视频免费| 欧美α片无限看在线观看免费| 天天做人人爱夜夜爽2020毛片| 欧美一级视| 亚洲精品影院久久久久久| 久久99这里只有精品国产| 亚洲 国产精品 日韩| 精品视频在线看| 欧美a级片免费看| 精品国产香蕉在线播出| 日本免费看视频| 色综合久久手机在线| 欧美国产日韩久久久| 青青久久国产成人免费网站| 日韩av东京社区男人的天堂| 韩国毛片免费| 日本久久久久久久 97久久精品一区二区三区 狠狠色噜噜狠狠狠狠97 日日干综合 五月天婷婷在线观看高清 九色福利视频 | 国产成a人片在线观看视频| 日韩中文字幕在线播放| 日韩专区一区| 久久国产一久久高清| 精品在线免费播放| 黄视频网站在线观看| 免费一级片在线| 久久精品欧美一区二区| 日韩在线观看视频免费| 精品久久久久久影院免费| 日韩欧美一二三区| 国产国产人免费视频成69堂| 午夜激情视频在线观看| 欧美另类videosbestsex久久| 你懂的福利视频| 日本在线不卡视频| 国产国语对白一级毛片| 亚洲精品中文一区不卡| 精品国产亚洲人成在线| 精品国产一区二区三区久久久蜜臀 | 99久久精品国产高清一区二区| 色综合久久久久综合体桃花网| 欧美18性精品| 精品国产香蕉伊思人在线又爽又黄| 亚洲天堂免费| 国产91精品一区| 沈樵在线观看福利| 一级女性大黄生活片免费| 免费的黄色小视频| 国产一区精品| 999精品视频在线| 亚州视频一区二区| 国产韩国精品一区二区三区| 美国一区二区三区| 亚洲第一页乱| 黄视频网站免费看| 欧美激情一区二区三区在线| 99色视频| 精品在线观看国产| 国产极品白嫩美女在线观看看| 欧美国产日韩久久久| 国产一区二区精品在线观看| 国产视频久久久久| 欧美另类videosbestsex视频| 99热视热频这里只有精品| 欧美激情一区二区三区视频 | 国产成a人片在线观看视频 | 国产伦精品一区三区视频| 一级女性全黄久久生活片| 国产a免费观看| 亚洲第一视频在线播放| 国产视频一区二区在线播放| 久久久成人网| 美女免费精品视频在线观看| 欧美大片a一级毛片视频| 成人a大片高清在线观看| 成人在激情在线视频| 成人a大片在线观看| 黄色免费三级| 精品在线观看一区| 日本免费区| 黄视频网站在线看| 欧美日本免费| 国产a毛片| 午夜欧美成人久久久久久| 国产麻豆精品| 欧美激情一区二区三区中文字幕| 精品国产亚一区二区三区| 韩国毛片免费大片| 欧美一区二区三区在线观看| 午夜久久网| 麻豆午夜视频| 一级毛片视频免费| 青青久久精品国产免费看| 国产麻豆精品视频| 国产极品白嫩美女在线观看看| 国产网站麻豆精品视频| 国产麻豆精品| 日本伦理网站| 欧美激情一区二区三区视频 | 欧美激情一区二区三区在线播放| a级毛片免费观看网站| 久久久久久久网| 国产精品自拍一区| 一级片片| 毛片高清| 99久久精品费精品国产一区二区| 色综合久久天天综合绕观看| 亚洲精品影院| 国产高清在线精品一区a| 日韩av东京社区男人的天堂| 可以在线看黄的网站| 四虎影视库| 久久精品道一区二区三区| 黄视频网站免费| 免费毛片播放| 一级片片| 成人免费高清视频| 日本伦理网站| 一本高清在线| 日韩字幕在线| 国产亚洲免费观看| 日韩在线观看免费完整版视频| 国产不卡高清| 国产一区免费观看| 国产a毛片| 午夜欧美成人香蕉剧场| 久久成人综合网| 久久国产精品自由自在| 国产网站麻豆精品视频| 青青久久精品国产免费看| 午夜激情视频在线播放| 99色视频| 日本久久久久久久 97久久精品一区二区三区 狠狠色噜噜狠狠狠狠97 日日干综合 五月天婷婷在线观看高清 九色福利视频 | 欧美a级片免费看| 超级乱淫伦动漫| 欧美另类videosbestsex高清| 你懂的福利视频| 国产麻豆精品免费视频| a级精品九九九大片免费看| 免费国产在线观看不卡|