1. 程式人生 > >利用redis實現分散式事務鎖,解決高併發環境下減庫存

利用redis實現分散式事務鎖,解決高併發環境下減庫存

http://download.redis.io/releases/

安裝:
sudo make test 測試編譯
sudo make install 
啟動:
redis-servre
cd “安裝目錄”
redis-server ./redis-3.2.9/redis.conf

問題描述:某電商平臺,首發一款新品手機,每人限購2臺,預計會有10W的併發,在該情況下,如果扣減庫存,保證不會超賣

方案一

利用資料庫鎖機制,對記錄進行鎖定,再進行操作 

SELECT * from goods where ID =1 for update;
UPDATE goods set stock = stock - 1;

利用排它鎖將並行轉化為序列操作,但該方案的效能和使用者體驗較差

方案二

利用redis 實現分散式鎖,

使用setnx命令(在key不存在時,建立並設定value 返回1,key存在時,會反回0)來獲取鎖,在業務邏輯中,我們可以通過這樣的方案來操作

	    Jedis client = jedisPool.getResource();
	    while(client.setnx("lock",String.valueOf(System.currentTimeMillis())) == 0){
	        Thread.sleep(10000);
	    }
	    ...........................
	    client.del("lock")

方案二進階

考慮到死鎖問題,即現成A獲取鎖後,宕機了,導致鎖一直無法釋放,我們可以通過get命令獲取鎖的時間戳,通過他進行超時判斷,並進行釋放

	    Long TIMEOUT_SECOUND = 120000L;
	    Jedis client = jedisPool.getResource();
	    while(client.setnx("lock",String.valueOf(System.currentTimeMillis())) == 0){
	        Long lockTime = Long.valueOf(client.get("lock"));
	        if (lockTime!=null && System.currentTimeMillis() > lockTime+TIMEOUT_SECOUND) {
	            client.del("lock");
            }
	        Thread.sleep(10000);
	    }
	    ...........................
	    ...........................
	    client.del("lock")

方案二加強

方案2的演算法中,為了確保在非超時情況下,鎖只能由有鎖的執行緒進行釋放,可以在value的時間戳中,拼上執行緒特徵碼

	    Long TIMEOUT_SECOUND = 120000L;
	    String featureCode = "machine01";
	    Jedis client = jedisPool.getResource();
	    while(client.setnx("lock",featureCode+":"+String.valueOf(System.currentTimeMillis())) == 0){
	        Long lockTime = Long.valueOf(client.get("lock").substring(9));
	        if (lockTime!=null && System.currentTimeMillis() > lockTime+TIMEOUT_SECOUND) {
	            client.del("lock");
            }
	        Thread.sleep(10000);
	    }
	    ...........................
	    ...........................
	    if (featureCode.equals(client.get("lock").substring(0, 8))) {
	        client.del("lock");
        }

相關推薦

併發場景系列(一) 利用redis實現分散式事務,解決併發環境庫存

問題描述:某電商平臺,首發一款新品手機,每人限購2臺,預計會有10W的併發,在該情況下,如果扣減庫存,保證不會超賣 方案一 利用資料庫鎖機制,對記錄進行鎖定,再進行操作  SELECT * from goods where ID =1 for updat

利用redis實現分散式事務,解決併發環境庫存

http://download.redis.io/releases/ 安裝: sudo make test 測試編譯 sudo make install 啟動: redis-servre cd “安裝目錄” redis-server ./redis-3.2.9/redis

Java多執行緒:解決併發環境資料插入重複問題

1.背景描述 應用框架:Spring + SpringMVC + Hibernate  資料庫:Oracle11g 一家文學網站向我係統推多執行緒低併發推送資料,我這邊觀察日誌和資料庫,發現有

利用Redis實現分散式 使用mysql樂觀解決併發問題

寫在最前面 我在之前總結冪等性的時候,寫過一種分散式鎖的實現,可惜當時沒有真正應用過,著實的心虛啊。正好這段時間對這部分實踐了一下,也算是對之前填坑了。 分散式鎖按照網上的結論,大致分為三種:1、資料庫樂觀鎖; 2、基於Redis的分散式鎖;3.、基於ZooKeeper的分散式鎖; 關於樂觀鎖的實現其實

利用Redis實現分散式

為什麼需要分散式鎖? 在傳統單體應用單機部署的情況下,可以使用Java併發相關的鎖,如ReentrantLcok或synchronized進行互斥控制。但是,隨著業務發展的需要,原單體單機部署的系統,漸漸的被部署在多機器多JVM上同時提供服務,這使得原單機部署情況下的併發控制鎖策略失效了,為了解決這個問

ZooKeeper分散式簡單實踐 利用Redis實現分散式

寫在最前面 前幾周寫了篇 利用Redis實現分散式鎖 ,今天簡單總結下ZooKeeper實現分散式鎖的過程。其實生產上我只用過Redis或者資料庫的方式,之前還真沒了解過ZooKeeper怎麼實現分散式鎖。這周簡單寫了個小Demo,更堅定了我繼續使用Redis的信心了。 ZooKeep

Redis利用 Redis 實現分散式

## 技術背景 首先我們需要先來了解下什麼是分散式鎖,以及為什麼需要分散式鎖。 對於這個問題,我們可以簡單將鎖分為兩種——記憶體級鎖以及分散式鎖,記憶體級鎖即我們在 Java 中的 synchronized 關鍵字(或許加上程序級鎖修飾更恰當些),而分散式鎖則是應用在分散式系統中的一種鎖機制。分散式鎖的應

關於利用MQ實現分散式事務的想法【轉】

轉自:https://www.jianshu.com/p/bafb09954f18   假設:訊息服務不丟訊息 場景 服務A 服務B 服務C 訊息服務Q 虛擬碼 服務A中 transaction{ A本地事務 B.callB(); C.callC(); A本地事務

PHP利用Mysql解決併發

前面寫過利用檔案鎖來處理高併發的問題的,現在我們說另外一個處理方式,利用Mysql的鎖來解決高併發的問題 先看沒有利用事務的時候併發的後果 建立庫存管理表 CREATE TABLE `storage` ( `id` int(11) unsigned NOT NULL AUTO_INCRE

SpringCloud定時任務需要用redis實現分散式全域性的相關操作

      我們知道現在微服務很流行,為此,許多中小型企業都將自己以前的框架加以改造,其中以SpringCloud為最多,但是SpringCloud如果要加定時任務的話,在單臺伺服器上很好支援,但是涉及到叢集服務(多臺服務的話)就要用到分散式鎖了,最簡單的方案是用R

C# 基於StackExchange.Redis.dll利用Redis實現分散式Session

最近在研發一款O2O產品,考慮到分散式架構的需要,以前那一套.NET的Session管理方式已經不合用了。遂研究了一下Redis,發現基於這種Key-Value的記憶體資料庫很適合來做分散式Session。本示例將基於StackExchange.Redis.dll進行實現,

使用mysql中的解決併發問題

為什麼要加鎖 多核計算機的出現,計算機實現真正平行計算,可以在同一時刻,執行多個任務。在多執行緒程式設計中,因為執行緒執行順序不可控導致的資料錯誤。比如,多執行緒的理想狀態是這樣的但是實際情況是這樣的: 在網路程式設計中,在同一時刻,多個客戶端同時請求同一個資源,如果不做控制,也會帶來資料錯誤。比如

redis解決併發定時秒殺”庫存誤差問題

前言:高併發的秒殺活動中,通過查詢資料庫判斷是否還有庫存,然後對庫存欄位進行增減,極易出現庫存超出或者庫存為負的情況,一般來說有3中解決辦法(資料庫表加鎖,memche快取,redis佇列);我們這裡使用redis來解決問題:1、思路:  1)觸發開始開團的同時,把庫存數量更

python 如何解決並發庫存問題??

問題 如何解決 時間 lba 悲觀鎖 font update 方法 llb python 提供了2種方法解決該問題的問題:1,悲觀鎖;2,樂觀鎖 悲觀鎖:在查詢商品儲存的時候加鎖 select_for_update() 在發生事務的commit或者是事務的rollb

併發併發環境詭異的加問題(你加的未必安全)

宣告 特此宣告:文中有關支付寶賬戶的說明,只是用來舉例,實際支付寶賬戶要比文中描述的複雜的多。也與文中描述的完全不同。 前言 很多網友留言說:在編寫多執行緒併發程式時,我明明對共享資源加鎖了啊?為什麼還是出問題呢?問題到底出在哪裡呢?其實,我想說的是:你的加鎖姿勢正確嗎?你真的會使用鎖嗎?錯誤的加鎖方式不但

併發環境執行緒安全的單例模式(最全最經典)

在所有的設計模式中,單例模式是我們在專案開發中最為常見的設計模式之一,而單例模式有很多種實現方式,你是否都瞭解呢?高併發下如何保證單例模式的執行緒安全性呢?如何保證序列化後的單例物件在反序列化後任然是單例的呢?這些問題在看了本文之後都會一一的告訴你答案,趕快來閱讀吧!什麼是單

資料庫 之 併發環境的規則

原文: 資料庫 之 高併發環境下的規則 本文大部分轉至沈劍老師,加上自己的一些見解。   本文前提 高併發環境   規則要點 1) 資料庫字符集使用utf8mb4 無亂碼風險、萬國碼 2)禁止使用儲存過程、檢視、觸發器、Event 高併發大資料的網際網路業務,架構設計思

圖文 併發環境HashMap的問題

我們來講解高併發環境下,HashMap可能出現的致命問題。                                 

併發環境,HashMap可能出現的致命問題。注意:是在jdk8以下版本

原文地址:https://blog.csdn.net/dgutliangxuan/article/details/78779448概念1:Rehash的概念? Rehash 是HashMap在擴容時候的一個步驟。HashMap的容量是有限的。當經過多次元素插入,使得HashM

併發環境生成訂單唯一流水號方法:SnowFlake

業務需求: 訂單號不能重複 訂單號沒有規則,即編碼規則不能加入任何和公司運營相關的數 據,外部人員無法通過訂單ID猜測到訂單量。不能被遍歷。 訂單號長度固定,且不能太長 易讀,易溝通,不要出現數字字母換亂現象 生成耗時 關於訂單號的生成,一些比較簡單的方案