• lock4j--分布式锁中间件--使用/实例


    原文网址:lock4j--分布式锁中间件--使用/实例_IT利刃出鞘的博客-CSDN博客

    简介

    说明

            本文用示例介绍分布式锁中间件lock4j 的用法。

    相关网址

    gitee:https://gitee.com/baomidou/lock4j

    github:https://github.com/baomidou/lock4j(Star数:68)

    lock4j的参考项目:https://gitee.com/kekingcn/spring-boot-klock-starter

    友情提示

            本人实际使用lock4j过程中遇到了很多问题,不推荐使用lock4j,推荐直接使用redisson的分布式锁。

    遇到的问题有:

    1. 获取锁超时时并没有抛异常,而是一直等待获取到锁

    概述

    1. lock4j与@Transactional类似:将注解写在方法上,自动控制上锁与释放锁。
    2. lock4j支持Redis(RedisTemplate或Redisson)、Zookeeper作为底层
      1. 2.0之后支持Redisson和Zookeeper
      2. 建议基于Redisson
        1. 原因:可以利用redisson的特性:自动续期等
        2. 方法:引入依赖:lock4j-redisson-spring-boot-starter
    3. 支持SPEL
    4. 执行顺序
      1. 如果在service上有@Transactional和@lock4j,则执行顺序如下
        1. 上锁
        2. 开启事务
        3. 执行逻辑
        4. 提交/回滚事务
        5. 释放锁
    5. 实现原理
      1. AOP:Advisor + methodInterception

    实例

            本文以Redisson为底层使用lock4j。

    依赖

    1. <dependency>
    2. <groupId>com.baomidou</groupId>
    3. <artifactId>lock4j-redisson-spring-boot-starter</artifactId>
    4. <version>2.2.2</version>
    5. </dependency>

    整个pom.xml

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    4. <modelVersion>4.0.0</modelVersion>
    5. <parent>
    6. <groupId>org.springframework.boot</groupId>
    7. <artifactId>spring-boot-starter-parent</artifactId>
    8. <version>2.4.13</version>
    9. <relativePath/> <!-- lookup parent from repository -->
    10. </parent>
    11. <groupId>com.knife.demo</groupId>
    12. <artifactId>demo_lock4j_SpringBoot</artifactId>
    13. <version>0.0.1-SNAPSHOT</version>
    14. <name>demo_lock4j_SpringBoot</name>
    15. <description>demo_lock4j_SpringBoot</description>
    16. <properties>
    17. <java.version>1.8</java.version>
    18. </properties>
    19. <dependencies>
    20. <dependency>
    21. <groupId>org.springframework.boot</groupId>
    22. <artifactId>spring-boot-starter-web</artifactId>
    23. </dependency>
    24. <!-- https://mvnrepository.com/artifact/com.baomidou/lock4j-redisson-spring-boot-starter -->
    25. <dependency>
    26. <groupId>com.baomidou</groupId>
    27. <artifactId>lock4j-redisson-spring-boot-starter</artifactId>
    28. <version>2.2.2</version>
    29. </dependency>
    30. <dependency>
    31. <groupId>org.projectlombok</groupId>
    32. <artifactId>lombok</artifactId>
    33. <optional>true</optional>
    34. </dependency>
    35. <dependency>
    36. <groupId>com.github.xiaoymin</groupId>
    37. <artifactId>knife4j-spring-boot-starter</artifactId>
    38. <version>3.0.3</version>
    39. </dependency>
    40. </dependencies>
    41. <build>
    42. <plugins>
    43. <plugin>
    44. <groupId>org.springframework.boot</groupId>
    45. <artifactId>spring-boot-maven-plugin</artifactId>
    46. <configuration>
    47. <excludes>
    48. <exclude>
    49. <groupId>org.projectlombok</groupId>
    50. <artifactId>lombok</artifactId>
    51. </exclude>
    52. </excludes>
    53. </configuration>
    54. </plugin>
    55. </plugins>
    56. </build>
    57. </project>

    配置

    application.yml

    1. spring:
    2. redis:
    3. host: 192.168.5.193
    4. port: 6379
    5. password: 222333
    6. #lock4j:
    7. # acquire-timeout: 3000 #默认值3s,可不设置
    8. # expire: 30000 #默认值30s,可不设置
    9. # primary-executor: com.baomidou.lock.executor.RedissonLockExecutor #默认redisson > redisTemplate > zookeeper,可不设置
    10. # lock-key-prefix: lock4j #锁key前缀, 默认值lock4j,可不设置

    代码

    Controller

    本处直接将@Lock4j写到Controller方法上,实际开发中应该写到Service的实现类的方法上。

    1. package com.knife.demo.controller;
    2. import com.baomidou.lock.annotation.Lock4j;
    3. import com.knife.demo.entity.User;
    4. import io.swagger.annotations.Api;
    5. import org.springframework.web.bind.annotation.GetMapping;
    6. import org.springframework.web.bind.annotation.RequestMapping;
    7. import org.springframework.web.bind.annotation.RestController;
    8. import java.util.List;
    9. @Api(tags = "用户")
    10. @RestController
    11. @RequestMapping("user")
    12. public class UserController {
    13. @GetMapping("listAll")
    14. @Lock4j
    15. public List<User> listAllUser() {
    16. return null;
    17. }
    18. @GetMapping("find")
    19. @Lock4j(keys = {"#user.id", "#user.name"}, expire = 60000, acquireTimeout = 1000)
    20. public List<User> find(User user) {
    21. return null;
    22. }
    23. }

    Entity

    1. package com.knife.demo.entity;
    2. import lombok.Data;
    3. @Data
    4. public class User {
    5. private Long id;
    6. private String name;
    7. }

    测试

    访问测试页面:http://localhost:8080/doc.html

    测试1:无参数、无选项

    运行前的Redis:(没有数据)

    打断点

    访问接口

    进入断点

    查看Redis信息(写入了数据)

    放开断点,方法执行结束(Redis数据被删除)

    测试2:有参数、有选项

     运行前的Redis:(没有数据)

    打断点

    访问接口(id赋值为:123,name赋值为:Tony)

    进入断点

    查看Redis信息(写入了数据)

    放开断点,方法执行结束(Redis数据被删除)

  • 相关阅读:
    两阶段终止模式
    【测试开发面试】6家企业真实面试,最终成功入职外企......
    1.5-19:救援
    Spring(十)- Spring Bean的基本注解
    SpringBoot-EasyExcel(大数据处理)
    2022年湖北省住建厅特种作业操作证怎么报考?甘建二
    USB Android HOST芯片沁恒股份CH9343
    程序员保密协议
    生产经验篇(2)——真实环境的MySQL机器配置规划
    如何实现CSDN评论区粉丝幸运抽选功能:一场代码与运气的碰撞
  • 原文地址:https://blog.csdn.net/feiying0canglang/article/details/125321100