我开发了一款只用一个注解就实现分布式锁的工具框架

相信大家在JAVA中知道锁的一个概念。在JAVA中,锁是一种机制,用于控制并发代码的执行。锁用于保护共享资源的访问,确保只有一个线程能够同时访问这些资源。锁可以防止多个线程同时执行对共享资源的修改操作,从而避免数据不一致或竞争条件。

但是呢JAVA里面的锁都是基于jvm的。就是说是一个服务独有的。这样的话,在分布式框架中就会有一个问题。比如说我有三个节点。大量的请求进来。我们的需求是不管你请求多少次,只会执行一次。假如说三个节点中每一个节点都进来了一个请求,这样的话就会出现执行了三次请求。这个时候就要请我们的分布式锁出场了。

分布式锁是一种用于在分布式系统中协调多个进程或节点访问共享资源的机制。它可以确保在多个节点上的操作不会发生冲突,避免数据不一致性和竞态条件问题。所以呢我就开发了一个只通过一个注解实现这个功能的工具框架(simple-cache)。

这次V1.4.0主要更新的内容为:

  • RedisLock注解实现分布锁

simple-cache-spring-boot-starter

请使用1.4.2版本

java 复制代码
	    <dependency>
            <groupId>io.gitee.antopen</groupId>
            <artifactId>simple-cache-spring-boot-starter</artifactId>
            <version>1.4.2</version>
        </dependency>

准备条件在博主的上一篇文章上门已经讲的很详细了,这次就不做讲解,只讲新功能

【simple-cache】一款只用一个注解就实现缓存的框架-我们终于迎来了SpringBoot版本

直接在bean类中添加@RedisLock注解即可。

说明:

@RedisLock可选值

属性 类型 必须指定 默认值 描述
value string 分布式锁的名称,可以自定义
expire long 10L(10秒) 锁超时时间,锁自动释放
unit TimeUnit TimeUnit.SECONDS(一秒) 时间单位。默认为秒。,可以修改
delWhenTaskComplete boolean true 任务执行完是否释放,可以修改
tips boolean 该任务正在执行,请稍后再试 有锁时返回的提示,可以修改

只有value属性的时候

只有value属性的时候当访问该方法的时候,redis里面会有一个叫testRLock的锁,默认过期时间为10s

java 复制代码
    @RedisLock(value = "testRLock")
    public String testRLock() {
        System.out.println("hello testRLock");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return "进入方法了";
    }

由于上面我们模拟了这个方法的执行时间为5秒钟,而且我们的delWhenTaskComplete默认值是true,所以没等10秒中过去,任务已经执行完并且自己释放锁了。如果我们在5秒内,也就是说锁还在的时候再次请求这个接口(方法),就会返回tips里面的提示:

expire值

java 复制代码
    @RedisLock(value = "testRLock",expire = 60L)
    public String testRLockexpire() {
        System.out.println("hello testRLock");
        try {
            Thread.sleep(500000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return "进入方法了";
    }

expire值默认是10s,大家可以根据自己项目实际情况去设置秒数,如上是会生成一个60s的锁。

unit值

java 复制代码
  @RedisLock(value = "testRLock", expire = 1L, unit = TimeUnit.HOURS)
    public String testRLockexpireAndunit() {
        System.out.println("hello testRLock");
        try {
            Thread.sleep(50000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return "进入方法了";
    }

unit值可以和expire 值结合使用,如上就是会生成一个小时的锁。

delWhenTaskComplete值

java 复制代码
   @RedisLock(value = "testRLock", delWhenTaskComplete = false)
    public String testRLockdelWhenTaskComplete() {
        System.out.println("hello testRLock");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return "进入方法了";
    }

delWhenTaskComplete默认是true,意思就是不管你锁的过期时间是多少,我任务执行完之后就会释放自己的锁,但是我们可以把他关闭,那么他就不会释放锁了,必须等到锁过期才能自动释放锁。建议大家在设置该值的时候按照实际业务调整和过期时间的设定,建议锁的过期时间要大于业务执行的时间,如果小于执行时间的话,锁就会优先过期掉了。

tips 值

java 复制代码
  @RedisLock(value = "testRLockTips", tips = "别急,等下再试!!")
    public String testRLockTips() {
        System.out.println("hello testRLock");
        try {
            Thread.sleep(50000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return "进入方法了";
    }

tips 是提示,大家可以自定义提示,例如上面的别急,等下再试!!

EL表达式

java 复制代码
    /**
     * 测试分布式锁
     *
     * @return string
     */
    @GetMapping("/testRLockId")
    public Object testRLockId() {

        return testRLockService.testRLockId(1);
    }
java 复制代码
  @RedisLock(value = "#id")
    public String testRLockId(Integer id) {
        System.out.println("hello testRLock");
        try {
            Thread.sleep(50000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return "进入方法了";
    }

同样,这个注解支持EL表达式,只要以#开头,值和入参名字一样即可,可参考上面的代码实现,上面就是把1作为唯一id作为锁的名称。

完整代码已经开源:

Simple Cache Spring Boot Starter

Simple Cache Spring Boot 快速启动代码

后续版本考虑:

  • 添加RedisCount注解,添加计数功能,例如网页访问量

如果有建议欢迎提出

如果你也想为开源贡献自己的力量,欢迎加入蚂蚁开源

使用simple-cache的springboot版本也十分简单,只需要:

  1. 引入simple-cache-spring-boot-starter依赖;
  2. 在启动类加上EnableSimpleCache注解;
  3. 在配置文件中填写属于你自己项目的redistemplate的bean的名称;
  4. 在你的业务类方法上添加simple-cache的注解
相关推荐
2401_8576009511 分钟前
企业OA管理系统:Spring Boot技术实践与案例分析
java·spring boot·后端
潜洋19 分钟前
Spring Boot 教程之六:Spring Boot - 架构
java·spring boot·后端·架构
尘浮生2 小时前
Java项目实战II基于SpringBoot的共享单车管理系统开发文档+数据库+源码)
java·开发语言·数据库·spring boot·后端·微信小程序·小程序
huaxiaorong2 小时前
如何将旧的Android手机改造为家用服务器
后端
2401_857439692 小时前
社团管理新工具:SpringBoot框架
java·spring boot·后端
2401_857610032 小时前
Spring Boot OA:企业办公自动化的创新之路
spring boot·后端·mfc
难念的码2 小时前
Skill 语言语法基础
人工智能·后端
我要改名叫嘟嘟2 小时前
四年时间读完100本书,结束时还记得且愿意分享的是这些
程序员
逸风尊者2 小时前
开发也能看懂的大模型:FNN
人工智能·后端·算法
2401_854391082 小时前
Spring Boot OA:企业数字化转型的利器
java·spring boot·后端