自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

SpringBoot強(qiáng)大的分布式鎖組件Lock4j,支持多種實(shí)現(xiàn)

開發(fā) 前端
lock4j是一個(gè)分布式鎖組件,其提供了多種不同的支持以滿足不同性能和環(huán)境的需求。底層通過Spring AOP技術(shù)實(shí)現(xiàn),而該切面的優(yōu)先級是最高的,也就是說當(dāng)你的環(huán)境中有多個(gè)切面時(shí)(如:聲明式事務(wù)),也不會(huì)導(dǎo)致失效問題。

環(huán)境:SpringBoot3.2.5

1. 簡介

lock4j是一個(gè)分布式鎖組件,其提供了多種不同的支持以滿足不同性能和環(huán)境的需求。底層通過Spring AOP技術(shù)實(shí)現(xiàn),而該切面的優(yōu)先級是最高的,也就是說當(dāng)你的環(huán)境中有多個(gè)切面時(shí)(如:聲明式事務(wù)),也不會(huì)導(dǎo)致失效問題。該組件具有如下2個(gè)特性:

  • 簡單易用,功能強(qiáng)大,擴(kuò)展性強(qiáng)。
  • 支持redission,redisTemplate,zookeeper??苫煊?,支持?jǐn)U展。

接下來將詳細(xì)介紹基于Redis的Lock4J使用。

2. 實(shí)戰(zhàn)案例

2.1 引入依賴

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

如果你想基于redisson或者是zookeeper實(shí)現(xiàn),那么你只需要引入對應(yīng)的包即可。

<!-- redisson -->
<artifactId>lock4j-redisson-spring-boot-starter</artifactId>
<!-- zookeeper -->
<artifactId>lock4j-zookeeper-spring-boot-starter</artifactId>
配置文件
spring:
  data:
    redis:
      timeout: 10000
      connectTimeout: 20000
      host: 127.0.0.1
      password: xxxooo
  #如果你是基于zookeeper實(shí)現(xiàn),那么做如下配置
  coordinate:
    zookeeper:
      zkServers: 127.0.0.1:2181,...

進(jìn)過以上的配置后接下來你就可以通過注解的方式使用分布式鎖了。

2.2 基本使用

@Service
public class StorageService {


  private final StorageRepository storageRepository ;
  public StorageService(StorageRepository storageRepository) {
    this.storageRepository = storageRepository ;
  }


  @Lock4j
  public void deductStorage(Long storageId, int count) {
    // TODO
  }
}

使用非常簡單,只需要在你需要上鎖的方法上添加@Lock4j注解即可。而這里將使用默認(rèn)行為:默認(rèn)獲取鎖超時(shí)3秒,30秒鎖過期。

自定義鎖key

在上面示例中沒有自定義@Lock4j注解的任何屬性;那么,將會(huì)使用默認(rèn)的key生成方式,上面的代碼將生成如下key。

# 前綴 + ":" + 完全限定類名+方法名+# (這里的#是固定的,如果你自定義了key,會(huì)在后面繼續(xù)拼接)
lock4j:com.pack.test.lock4j.StorageServicedeductStorage#

當(dāng)我們自定義了key后如下:

@Lock4j(key = "#storageId")
public void deductStorage(Long storageId, int count)

key支持Spring SpEL表達(dá)式,如上將生成如下的key

# 方法調(diào)用storageService.deductStorage(1, 2) ;
lock4j:com.pack.test.lock4j.StorageServicedeductStorage#1

你也可以不使用SpEL表達(dá)式。不使用SpEL表達(dá)式那么就需要使用如下語法

@Lock4j(keys = "'storageId'")
public void deductStorage(...) {}

沒有使用單引號程序?qū)?huì)報(bào)錯(cuò)。

設(shè)置過期時(shí)間

默認(rèn)獲取鎖超時(shí)3秒,30秒鎖過期,可以通過如下屬性配置過期時(shí)間

@Lock4j(keys = {"#storageId"}, expire = 3000, acquireTimeout = 3000)
public void deductStorage(Long storageId, int count) {}

expire: 鎖過期時(shí)間(毫秒);注:鎖過期時(shí)間必須要大于業(yè)務(wù)處理時(shí)間。acquireTimeout: 獲取鎖超時(shí)時(shí)間(毫秒)

以上是Lock4j的基本用法;下面將介紹Lock4j其它高級用法。

2.3 高級用法

全局統(tǒng)一配置

lock4j:
  acquire-timeout: 3000 
  expire: 30000
  primary-executor: com.baomidou.lock.executor.RedisTemplateLockExecutor
  lock-key-prefix: lock4j

primary-executor:配置加鎖的實(shí)現(xiàn)方式;默認(rèn)順序是:
redisson > redisTemplate > zookeeper;如果你的環(huán)境中這3個(gè)都引入了,那么就是按照這個(gè)順序,因?yàn)槎x他們時(shí)使用了@Order注解聲明順序。lock-key-prefix:#鎖前綴,如上面示例看到的lock4j為默認(rèn)值。

自定義執(zhí)行器(加鎖)

我們可以通過實(shí)現(xiàn)LockExecutor接口定義自己的加鎖實(shí)現(xiàn),比如基于MySQL實(shí)現(xiàn)。如下:

@Component
public class JdbcLockExecutor implements LockExecutor<String> {


  private final JdbcTemplate jdbcTemplate ;
  public JdbcLockExecutor(JdbcTemplate jdbcTemplate) {
    this.jdbcTemplate = jdbcTemplate ;
  }
  @Override
  public String acquire(String lockKey, String lockValue, long expire, long acquireTimeout) {
    // TODO; 獲取鎖
    return null ;
  }
  @Override
  public boolean releaseLock(String key, String value, String lockInstance) {
    // TODO; 釋放鎖
    return false;
  }
}

注:這里必須要注冊為Spring Bean。否則將無法獲取。使用如下:

@Lock4j(executor = JdbcLockExecutor.class)
public void deductStorage(Long storageId, int count) {}

加鎖時(shí)會(huì)根據(jù)這里配置的executor Class對象獲取Spring容器對應(yīng)的bean對象。

自定義key生成器

Lock4j默認(rèn)的鎖key生成器為DefaultLockKeyBuilder,我們可以通過LockKeyBuilder接口實(shí)現(xiàn)自己的key生成方式

@Component
public class PackLockKeyBuilder implements LockKeyBuilder {


  @Override
  public String buildKey(MethodInvocation invocation, String[] definitionKeys) {
    // TODO; 生成key
    return null;
  }
}

注:這里也必須注冊為bean對象。使用如下:

@Lock4j(keyBuilderStrategy = PackLockKeyBuilder.class)
public void deductStorage(Long storageId, int count) {}

內(nèi)部會(huì)通過你這里配置的Class對象獲取對應(yīng)的Spring Bean實(shí)例對象。

自定義獲取鎖失敗策略

當(dāng)獲取鎖失敗時(shí)如何進(jìn)行處理?默認(rèn)實(shí)現(xiàn)是DefaultLockFailureStrategy通過自定義LockFailureStrategy,實(shí)現(xiàn)自己的邏輯。與上面的套路一樣都需要注冊為bean。

@Component
public class PackLockFailureStrategy implements LockFailureStrategy {


  @Override
  public void onLockFailure(String key, Method method, Object[] arguments) {
    // TODO
  }
}

使用如下:

@Lock4j(failStrategy = PackLockFailureStrategy.class)
public void deductStorage(Long storageId, int count) {}

注:這里你也可以不指定failStrategy屬性,會(huì)自動(dòng)從容器中查找對應(yīng)的實(shí)現(xiàn)Bean。

非注解實(shí)現(xiàn)方式(手動(dòng)加鎖/釋放鎖)

你也可以通過注入LockTemplate對象,由自己來完成加鎖和釋放鎖的動(dòng)作。

private final LockTemplate lockTemplate ;
  public StorageService(LockTemplate lockTemplate) {
    this.lockTemplate = lockTemplate ;
  }
  public void deductStorage(Long storageId, int count) {
    String key = "xxxx" ;
    final LockInfo lockInfo = lockTemplate.lock(key, 30000L, 5000L, RedisTemplateLockExecutor.class);
    if (null == lockInfo) {
        throw new RuntimeException("業(yè)務(wù)處理中,請稍后再試") ;
    }
    // 獲取鎖成功,處理業(yè)務(wù)
    try {
        // TODO
    } finally {
        // 釋放鎖
        lockTemplate.releaseLock(lockInfo) ;
    }
  }
}

手動(dòng)加鎖方式,一般適用于需要更細(xì)粒度控制鎖邊界,否則沒必要。

責(zé)任編輯:武曉燕 來源: Spring全家桶實(shí)戰(zhàn)案例源碼
相關(guān)推薦

2017-01-16 14:13:37

分布式數(shù)據(jù)庫

2018-04-03 16:24:34

分布式方式

2022-04-08 08:27:08

分布式鎖系統(tǒng)

2023-01-13 07:39:07

2024-11-28 15:11:28

2023-09-04 08:12:16

分布式鎖Springboot

2021-07-13 06:57:12

SpringbootAOP緩存

2019-06-19 15:40:06

分布式鎖RedisJava

2021-02-28 07:49:28

Zookeeper分布式

2017-04-13 10:51:09

Consul分布式

2019-02-26 09:51:52

分布式鎖RedisZookeeper

2023-08-21 19:10:34

Redis分布式

2022-01-06 10:58:07

Redis數(shù)據(jù)分布式鎖

2021-10-25 10:21:59

ZK分布式鎖ZooKeeper

2024-10-09 17:12:34

2018-04-09 09:15:32

數(shù)據(jù)庫DB分布式鎖

2023-03-01 08:07:51

2022-10-27 10:44:14

分布式Zookeeper

2023-09-13 09:52:14

分布式鎖Java

2023-08-27 22:13:59

Redisson分布式緩存
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號