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

Spring?Boot?3.0x的Redis?分布式鎖的概念和原理

 更新時間:2024年08月29日 12:12:28   作者:???傀儡師  
Redis?分布式鎖是一種基于?Redis?的分布式鎖解決方案,它的原理是利用?Redis?的原子性操作實現(xiàn)鎖的獲取和釋放,從而保證共享資源的獨占性,這篇文章主要介紹了適合?Spring?Boot?3.0x的Redis?分布式鎖,需要的朋友可以參考下

Spring Boot 中的 Redis 分布式鎖

在分布式系統(tǒng)中,多個進程同時訪問共享資源時,很容易出現(xiàn)并發(fā)問題。為了避免這些問題,我們可以使用分布式鎖來保證共享資源的獨占性。Redis 是一款非常流行的分布式緩存,它也提供了分布式鎖的功能。在 Spring Boot 中,我們可以很容易地使用 Redis 分布式鎖來管理并發(fā)訪問。

本文將介紹 Redis 分布式鎖的概念和原理,并說明如何在 Spring Boot 中使用它們。

Redis 分布式鎖的概念和原理

Redis 分布式鎖是一種基于 Redis 的分布式鎖解決方案。它的原理是利用 Redis 的原子性操作實現(xiàn)鎖的獲取和釋放,從而保證共享資源的獨占性。

spring boot 項目引入

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>lock4j-redis-template-spring-boot-starter</artifactId>
    <version>2.2.7</version>
</dependency>

在需要加分布式鎖的方法上,添加注解@Lock4j

1.@Lock4j 注解的功能
獲取鎖超時(acquireTimeout):指定在獲取鎖時的等待時間,默認情況下是 3 秒。如果在這段時間內(nèi)無法獲取到鎖,可能會拋出異?;蜻M行相應(yīng)的處理。

鎖過期時間(expire):指定鎖的過期時間,默認是 30 秒。如果在這段時間內(nèi)鎖沒有被手動釋放,它會自動失效。這個機制通常用于防止死鎖。

SpEL 表達式支持:@Lock4j 支持使用 SpEL 表達式來動態(tài)生成鎖的鍵(key),例如通過方法參數(shù)生成唯一的鎖標識。

@Service
public class DemoServiceImpl {
    /**
    默認獲取鎖超時3秒,30秒鎖過期
    這個方法使用了 @Lock4j 注解,并且沒有顯式地配置任何參數(shù)。
	默認行為:獲取鎖時的超時時間為 3 秒,鎖的過期時間為 30 秒。
	適用場景:在簡單的場景下,simple() 方法會被鎖住,直到鎖被釋放或超時。在鎖的持有期間,其他線程無法進入該方法。
	**/
    @Lock4j
    public void simple() {
        //需要執(zhí)行的方法
    }
    /**
    完全配置,支持spel,這個方法使用了 @Lock4j 注解,并且自定義了多個參數(shù)。
	配置詳解:
	keys = {"#user.id", "#user.name"}:使用 SpEL 表達式動態(tài)生成鎖的鍵。這里鎖的鍵由 user 對象的 id 和 name 屬性組成,確保了鎖的唯一性。
	expire = 60000:指定鎖的過期時間為 60 秒(即1分鐘)。
	acquireTimeout = 1000:指定獲取鎖的超時時間為 1 秒。
	適用場景:當方法涉及到特定用戶操作時,使用 customMethod() 來確保同一用戶(根據(jù) id 和 name 唯一確定)不會被多個線程同時操作。只有在獲取到鎖的情況下,才會執(zhí)行方法邏輯,鎖在1秒內(nèi)未獲取到,則會拋出異?;驁?zhí)行相應(yīng)處理。
	**/
    @Lock4j(keys = {"#user.id", "#user.name"}, expire = 60000, acquireTimeout = 1000)
    public User customMethod(User user) {
        return user;
    }
}

設(shè)置配置文件的

lock4j:
  acquire-timeout: 3000 # 默認獲取鎖超時時間為3秒
  expire: 30000 # 默認鎖的過期時間為30秒
  primary-executor: com.baomidou.lock.executor.RedisTemplateLockExecutor # 使用RedisTemplate作為默認的鎖執(zhí)行器
  lock-key-prefix: lock4j # 鎖key的前綴,默認為lock4j

配置項詳解
acquire-timeout: 3000

含義:指定全局默認的獲取鎖的超時時間,單位為毫秒。默認設(shè)置為3秒(3000毫秒)。如果在這個時間內(nèi)未能獲取到鎖,將觸發(fā)相應(yīng)的處理邏輯(比如拋出異常)。
使用場景:適用于全局大多數(shù)鎖的場景,可以減少在每個注解中重復(fù)配置的需要。
expire: 30000

含義:指定全局默認的鎖過期時間,單位為毫秒。默認設(shè)置為30秒(30000毫秒)。在這個時間內(nèi),如果鎖沒有被釋放,它將自動失效。
使用場景:適用于防止死鎖的全局場景,確保鎖在一定時間內(nèi)自動釋放,避免持有鎖的線程因故障而導(dǎo)致鎖無法釋放。
primary-executor: com.baomidou.lock.executor.RedisTemplateLockExecutor

含義:指定默認使用的分布式鎖執(zhí)行器。這個配置定義了使用哪種方式來實現(xiàn)鎖的邏輯,常見的選項包括 Redisson, RedisTemplate, 和 Zookeeper。
使用場景:這里指定使用 RedisTemplateLockExecutor 來實現(xiàn)分布式鎖邏輯,適用于大多數(shù)基于Redis的分布式系統(tǒng)。
lock-key-prefix: lock4j

含義:為鎖的鍵(key)指定一個全局前綴。這個前綴會被添加到所有的鎖鍵之前,以確保鎖鍵的唯一性。
使用場景:適用于多個應(yīng)用共享一個Redis實例時,通過設(shè)置前綴來防止不同應(yīng)用之間的鎖鍵沖突。

用法

    @Lock4j(executor = RedissonLockExecutor.class)
    public Boolean test() {
        return "true";
    }

自定義鎖key生成器,默認的鎖key生成器為 com.baomidou.lock.DefaultLockKeyBuilder

@Component
public class DynamicLockKeyBuilder extends DefaultLockKeyBuilder {
    @Override
	public String buildKey(MethodInvocation invocation, String[] definitionKeys) {
		String key = super.buildKey(invocation, definitionKeys);
        //需要執(zhí)行的方法
		return key;
	}
}

自定義鎖獲取失敗策略,默認的鎖獲取失敗策略為 com.baomidou.lock.DefaultLockFailureStrategy

@Component
public class MyLockFailureStrategy implements LockFailureStrategy {
    @Override
    public void onLockFailure(String key, long acquireTimeout, int acquireCount) {
    	//需要執(zhí)行的方法或者業(yè)務(wù)代碼
    }
}

手動上鎖或手動解鎖

@Service
@AllArgsConstructor
public class SysPaymentInfoServiceImpl extends ServiceImpl<SysPaymentInfoMapper, SysPaymentInfo> implements SysPaymentInfoService {
    private final LockTemplate lockTemplate;
    public void programmaticLock(String userId) {
        // 執(zhí)行查詢業(yè)務(wù)操作 不上鎖
        // 業(yè)務(wù)區(qū)域
        // 獲取鎖
        final LockInfo lockInfo = lockTemplate.lock(userId, 30000L, 5000L, RedissonLockExecutor.class);
        if (null == lockInfo) {
            throw new RuntimeException("業(yè)務(wù)處理中,請稍后再試!");
        }
        // 獲取鎖成功,處理相關(guān)業(yè)務(wù)
        try {
            Console.log("執(zhí)行簡單方法 , 當前線程:" + Thread.currentThread().getName() + " , counter:" + (counter++));
        } finally {
            //釋放鎖
            lockTemplate.releaseLock(lockInfo);
        }
        //結(jié)束
    }

指定時間內(nèi)不釋放鎖(限流)

// 用戶在5秒內(nèi)只能訪問1次
    @Lock4j(keys = {"#user.id"}, acquireTimeout = 0, expire = 5000, autoRelease = false)
    public Boolean test(User user) {
        return "true";
    }

1.@Lock4j(keys = {“#user.id”})
含義:使用 SpEL 表達式 #user.id 生成鎖的鍵。鎖的鍵與傳入的 user.id 關(guān)聯(lián),確保鎖的唯一性。這樣可以保證每個用戶(根據(jù)其 id)都會有一個唯一的鎖。
2.acquireTimeout = 0
含義:獲取鎖的超時時間設(shè)置為 0,表示立即嘗試獲取鎖,不等待。如果無法獲取鎖,則直接放棄操作。
使用場景:當你希望方法調(diào)用立即失敗而不等待時,這個配置很有用。適用于需要快速響應(yīng)的場景。
3.expire = 5000
含義:鎖的過期時間設(shè)置為 5000 毫秒(5 秒)。鎖在 5 秒后自動失效,釋放鎖資源。
使用場景:這個配置用于控制用戶只能在 5 秒內(nèi)訪問一次該方法,5 秒后鎖自動失效,用戶可以再次訪問。
4.autoRelease = false
含義:設(shè)置 autoRelease = false 表示鎖不會在方法執(zhí)行完畢后自動釋放。通常,默認情況下,鎖在方法執(zhí)行完畢后會自動釋放,但在這里顯式關(guān)閉了這個功能。
使用場景:這種配置可能用于場景中需要手動控制鎖的釋放,而不是依賴方法執(zhí)行結(jié)束后自動釋放的情況。例如,你可能希望鎖在一定時間后自然過期,而不是方法執(zhí)行完畢就立即釋放。

到此這篇關(guān)于適合 Spring Boot 3.0x的Redis 分布式鎖的文章就介紹到這了,更多相關(guān)Spring Boot Redis 分布式鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Redis實現(xiàn)限流器的三種方法(小結(jié))

    Redis實現(xiàn)限流器的三種方法(小結(jié))

    本文主要介紹了Redis實現(xiàn)限流器的三種方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • redis列表類型_動力節(jié)點Java學(xué)院整理

    redis列表類型_動力節(jié)點Java學(xué)院整理

    這篇文章主要為大家詳細介紹了redis列表類型的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • 深入理解Redis被覆寫后的失效時間

    深入理解Redis被覆寫后的失效時間

    Redis覆寫已存在的鍵會導(dǎo)致其舊的失效時間被新的鍵值對所取代,本文詳細解析了在鍵被覆寫時,其失效時間的變化,具有一定的參考價值,感興趣的可以了解一下
    2024-09-09
  • 你了解Redis事務(wù)嗎

    你了解Redis事務(wù)嗎

    說到事務(wù),大家會立刻想到Mysql的事務(wù),所謂的事務(wù)就是對數(shù)據(jù)進行一系列的操作,要么都執(zhí)行成功,要么都執(zhí)行失敗,下面就介紹一下Redis如何實現(xiàn)事務(wù),感興趣的可以了解一下
    2022-08-08
  • 基于session?Redis實現(xiàn)登錄

    基于session?Redis實現(xiàn)登錄

    這篇文章主要介紹了基于session?Redis實現(xiàn)登錄的相關(guān)資料,需要的朋友可以參考下
    2023-10-10
  • redis如何清理緩存

    redis如何清理緩存

    本文主要介紹了redis如何清理緩存,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • 詳解Redis SCAN命令實現(xiàn)有限保證的原理

    詳解Redis SCAN命令實現(xiàn)有限保證的原理

    這篇文章主要介紹了Redis SCAN命令實現(xiàn)有限保證的原理,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值 ,需要的朋友可以參考下
    2019-07-07
  • Redis之Redisson原理詳解

    Redis之Redisson原理詳解

    Redisson 顧名思義,Redis 的兒子,本質(zhì)上還是 Redis 加鎖,不過是對 Redis 做了很多封裝,它不僅提供了一系列的分布式的 Java 常用對象,還提供了許多分布式服務(wù),本文將詳細給大家介紹Redisson原理
    2023-06-06
  • Redis集群水平擴展、集群中添加以及刪除節(jié)點的操作

    Redis集群水平擴展、集群中添加以及刪除節(jié)點的操作

    這篇文章主要介紹了Redis集群水平擴展、集群中添加以及刪除節(jié)點的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03
  • Redis安裝啟動及常見數(shù)據(jù)類型

    Redis安裝啟動及常見數(shù)據(jù)類型

    這篇文章主要介紹了Redis安裝啟動及常見數(shù)據(jù)類型,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04

最新評論