欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

redis樂觀鎖與悲觀鎖的實戰(zhàn)?

 更新時間:2023年04月13日 08:35:42   作者:不拿博客專家不改名  
Redis提供了兩種鎖機制,即樂觀鎖和悲觀鎖。本文主要介紹了redis樂觀鎖與悲觀鎖的實戰(zhàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

概念

Redis是一個內(nèi)存中的鍵值存儲系統(tǒng),支持多種數(shù)據(jù)結構,如字符串、哈希、列表等。Redis提供了兩種鎖機制,即樂觀鎖和悲觀鎖。

樂觀鎖

樂觀鎖是一種樂觀的并發(fā)控制策略,它認為數(shù)據(jù)在大多數(shù)情況下不會被其他線程占用,因此每次需要修改數(shù)據(jù)時,都不會獲取鎖,而是直接進行修改。在Redis中,可以通過WATCH和CAS命令來實現(xiàn)樂觀鎖,WATCH命令用于監(jiān)視一個或多個鍵,CAS命令用于檢查并更新鍵的值。

例如,假設有一個計數(shù)器鍵counter,多個客戶端都需要對其進行操作。使用樂觀鎖的方式,可以在每個客戶端執(zhí)行操作之前,先通過WATCH命令監(jiān)視counter鍵:

WATCH counter
current_count = GET counter
new_count = current_count + 1
MULTI
SET counter new_count
EXEC

然后,在EXEC命令執(zhí)行之前,使用GET命令再次獲取counter鍵的值,并將其與之前獲取的值進行比較。如果值相等,就說明期間沒有其他客戶端對counter鍵進行了修改,此時可以使用CAS命令將新值設置到counter鍵中。如果值不相等,則說明期間有其他客戶端對counter鍵進行了修改,需要重新執(zhí)行操作。

GET counter

悲觀鎖

悲觀鎖是一種悲觀的并發(fā)控制策略,它認為數(shù)據(jù)在大多數(shù)情況下都會被其他線程占用,因此每次需要修改數(shù)據(jù)時,都會先獲取鎖,確保在修改期間沒有其他線程可以訪問該數(shù)據(jù)。在Redis中,可以通過WATCH命令來實現(xiàn)悲觀鎖,該命令可以監(jiān)視一個或多個鍵,如果在事務執(zhí)行期間有任何被監(jiān)視鍵的值發(fā)生了變化,整個事務會被回滾。

還是上文的例子

WATCH counter
current_count = GET counter
new_count = current_count + 1
MULTI
SET counter new_count
EXEC

如果在執(zhí)行事務期間,有其他客戶端修改了counter鍵,那么整個事務會被回滾,需要重新執(zhí)行。

悲觀鎖的優(yōu)點在于它可以確保數(shù)據(jù)的一致性,但缺點在于它需要獲取鎖,可能會引起線程的阻塞,影響并發(fā)性能。

樂觀鎖示例

假設有一個電商平臺,用戶可以在平臺上購買商品。為了保證數(shù)據(jù)的一致性,我們可以使用Redis的樂觀鎖來實現(xiàn)商品庫存的扣減。

首先,我們需要在Redis中保存每個商品的庫存信息,使用hash數(shù)據(jù)結構來保存,例如:

然后,在業(yè)務邏輯中,當用戶購買一個商品時,需要執(zhí)行以下步驟:

  • 使用WATCH命令監(jiān)視商品庫存鍵,例如stock:sku001;
  • 使用GET命令獲取當前商品庫存數(shù)量;
  • 檢查商品庫存是否足夠,如果不足,直接返回錯誤信息;
  • 計算新的庫存數(shù)量,并使用MULTI命令開啟一個事務;
  • 使用HSET命令將新的庫存數(shù)量保存到Redis中;
  • 執(zhí)行事務,如果在執(zhí)行期間有其他客戶端修改了商品庫存,會回滾事務,需要重新執(zhí)行。

下面是使用Spring Boot實現(xiàn)的示例代碼:

@Service
public class OrderService {
? ? private final RedisTemplate<String, Integer> redisTemplate;

? ? @Autowired
? ? public OrderService(RedisTemplate<String, Integer> redisTemplate) {
? ? ? ? this.redisTemplate = redisTemplate;
? ? }

? ? public void placeOrder(String sku, int quantity) {
? ? ? ? String stockKey = "stock:" + sku;
? ? ? ? while (true) {
? ? ? ? ? ? // 監(jiān)視商品庫存鍵,以便在事務開始前檢測是否有其他客戶端修改了庫存
? ? ? ? ? ? redisTemplate.watch(stockKey);
? ? ? ? ? ? // 獲取當前庫存數(shù)量
? ? ? ? ? ? int currentStock = redisTemplate.opsForHash().get(stockKey, sku);
? ? ? ? ? ? // 檢查庫存是否足夠
? ? ? ? ? ? if (currentStock < quantity) {
? ? ? ? ? ? ? ? // 庫存不足,放棄事務并拋出異常
? ? ? ? ? ? ? ? redisTemplate.unwatch();
? ? ? ? ? ? ? ? throw new RuntimeException("Out of stock");
? ? ? ? ? ? }
? ? ? ? ? ? // 計算新的庫存數(shù)量
? ? ? ? ? ? int newStock = currentStock - quantity;
? ? ? ? ? ? // 開始事務
? ? ? ? ? ? redisTemplate.multi();
? ? ? ? ? ? // 更新庫存數(shù)量
? ? ? ? ? ? redisTemplate.opsForHash().put(stockKey, sku, newStock);
? ? ? ? ? ? // 提交事務
? ? ? ? ? ? List<Object> results = redisTemplate.exec();
? ? ? ? ? ? // 如果事務執(zhí)行成功,則退出循環(huán)
? ? ? ? ? ? if (results != null) {
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? }
? ? ? ? ? ? // 如果事務執(zhí)行失敗,則重試
? ? ? ? }
? ? }
}

在上面的代碼中,我們使用RedisTemplate來操作Redis,其中watch方法用于監(jiān)視商品庫存鍵,opsForHash方法用于獲取和修改商品庫存的值,multi和exec方法用于開啟和提交事務。

悲觀鎖示例

除了樂觀鎖,Redis還支持悲觀鎖,可以通過設置NX(Not Exist)或XX(Exist)標志來實現(xiàn)。例如,當NX標志設置為true時,如果鎖不存在,會返回OK,并創(chuàng)建一個鎖;如果鎖已經(jīng)存在,會返回null,表示獲取鎖失敗。反之,當XX標志設置為true時,如果鎖已經(jīng)存在,會返回OK,表示獲取鎖成功;如果鎖不存在,會返回null,表示獲取鎖失敗。

下面是使用Spring Boot實現(xiàn)的悲觀鎖示例代碼:

@Service
public class OrderService {
? ? private final RedisTemplate<String, String> redisTemplate;

? ? @Autowired
? ? public OrderService(RedisTemplate<String, String> redisTemplate) {
? ? ? ? this.redisTemplate = redisTemplate;
? ? }

? ? public void placeOrder(String sku, int quantity) {
? ? ? ? String lockKey = "lock:" + sku;
? ? ? ? // 嘗試獲取鎖,如果鎖已經(jīng)存在,說明有其他線程正在執(zhí)行相關操作
? ? ? ? Boolean locked = redisTemplate.opsForValue().setIfAbsent(lockKey, "locked");
? ? ? ? if (!locked) {
? ? ? ? ? ? // 獲取鎖失敗,拋出異常
? ? ? ? ? ? throw new RuntimeException("Unable to acquire lock");
? ? ? ? }
? ? ? ? // 設置鎖的過期時間,防止鎖被一直占用
? ? ? ? redisTemplate.expire(lockKey, 10, TimeUnit.SECONDS);
? ? ? ? try {
? ? ? ? ? ? // 執(zhí)行訂單創(chuàng)建、扣減庫存等操作
? ? ? ? } finally {
? ? ? ? ? ? // 釋放鎖
? ? ? ? ? ? redisTemplate.delete(lockKey);
? ? ? ? }
? ? }
}

在上面的代碼中,我們使用setIfAbsent方法來嘗試獲取鎖,如果鎖已經(jīng)存在,說明其他線程正在執(zhí)行相關操作,此時會返回false,表示獲取鎖失??;否則,會返回true,表示獲取鎖成功。如果獲取鎖成功,我們會設置鎖的過期時間,并執(zhí)行相關操作,最后釋放鎖。

總結提升

需要注意的是,悲觀鎖一般適用于并發(fā)量不大的場景,如果并發(fā)量較高,容易導致性能問題。因此,在實際應用中,需要根據(jù)具體情況選擇合適的鎖策略。

到此這篇關于redis樂觀鎖與悲觀鎖的實戰(zhàn) 的文章就介紹到這了,更多相關redis樂觀鎖與悲觀鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Linux下redis密碼和遠程連接方式

    Linux下redis密碼和遠程連接方式

    這篇文章主要介紹了Linux下redis密碼和遠程連接方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • 搭建Redis服務器步驟詳細介紹

    搭建Redis服務器步驟詳細介紹

    大家好,本篇文章主要講的是搭建Redis服務器步驟詳細介紹,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • Windows操作系統(tǒng)下Redis服務安裝圖文教程

    Windows操作系統(tǒng)下Redis服務安裝圖文教程

    這篇文章主要介紹了Windows操作系統(tǒng)下Redis服務安裝圖文教程,文中給大家提供了redis的下載地址,安裝程序步驟,需要的朋友可以參考下
    2018-03-03
  • CentOS系統(tǒng)下Redis安裝和自啟動配置的步驟

    CentOS系統(tǒng)下Redis安裝和自啟動配置的步驟

    相信大家都知道Redis是一個C實現(xiàn)的基于內(nèi)存、可持久化的鍵值對數(shù)據(jù)庫,在分布式服務中常作為緩存服務。所以這篇文章將詳細介紹在CentOS系統(tǒng)下如何從零開始安裝到配置啟動服務。有需要的可以參考借鑒。
    2016-09-09
  • 銀河麒麟V10sp1服務器系統(tǒng)安裝redis不能使用的快速解決辦法

    銀河麒麟V10sp1服務器系統(tǒng)安裝redis不能使用的快速解決辦法

    這篇文章主要介紹了銀河麒麟V10sp1服務器系統(tǒng)安裝redis不能使用的快速解決辦法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-01-01
  • Redis批量刪除Key的三種方式小結

    Redis批量刪除Key的三種方式小結

    本文主要介紹了Redis批量刪除Key的三種方式小結,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-04-04
  • Redis教程(七):Key操作命令詳解

    Redis教程(七):Key操作命令詳解

    這篇文章主要介紹了Redis教程(七):Key操作命令詳解,本文講解了Key操作命令概述、相關命令列表、命令使用示例等內(nèi)容,需要的朋友可以參考下
    2015-04-04
  • window下創(chuàng)建redis出現(xiàn)問題小結

    window下創(chuàng)建redis出現(xiàn)問題小結

    這篇文章主要介紹了window下創(chuàng)建redis出現(xiàn)問題總結,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-10-10
  • redis?設置生存和過期時間的原理分析

    redis?設置生存和過期時間的原理分析

    這篇文章主要介紹了redis?設置生存和過期時間的原理,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • 使用Redis實現(xiàn)點贊取消點贊的詳細代碼

    使用Redis實現(xiàn)點贊取消點贊的詳細代碼

    這篇文章主要介紹了Redis實現(xiàn)點贊取消點贊的詳細代碼,通過查詢某實體(帖子、評論等)點贊數(shù)量,需要用到事務相關知識,結合示例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2022-03-03

最新評論