疯狂的狮子li
2021-06-22 f098222a43bb37a94563fd83932d8cc2becac1c2
update 集成 Lock4j 分布式锁
已修改6个文件
148 ■■■■ 文件已修改
README.md 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application-dev.yml 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application.yml 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java 49 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-demo/src/main/java/com/ruoyi/demo/service/ITestDemoService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestDemoServiceImpl.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
README.md
@@ -21,6 +21,8 @@
* 序列化框架 统一使用 jackson 高效可靠
* 代码生成器 一键生成前后端代码
* 多数据源框架 dynamic-datasource 支持主从与多种类数据库异构
* Redis客户端 采用 Redisson 性能更强
* 分布式锁 Lock4j 注解锁、工具锁 多种多样
## 参考文档
@@ -43,6 +45,7 @@
* 增加 redisson 高性能 Redis 客户端
* 移除 fastjson 统一使用 jackson 序列化
* 集成 dynamic-datasource 多数据源(默认支持MySQL,其他种类需自行适配)
* 集成 Lock4j 实现分布式 注解锁、工具锁 多种多样
### 代码改动
ruoyi-admin/src/main/resources/application-dev.yml
@@ -1,21 +1,27 @@
# 数据源配置
spring:
  autoconfigure:
    exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    # 动态数据源文档 https://www.kancloud.cn/tracy5546/dynamic-datasource/content
    dynamic:
      #设置默认的数据源或者数据源组,默认值即为 master
      primary: master
      datasource:
        # 主库数据源
        master:
          driverClassName: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true
          username: root
          password: root
        # 从库数据源
        slave:
          driverClassName: com.mysql.cj.jdbc.Driver
          url:
          username:
          password:
    druid:
      # 主库数据源
      master:
        url: jdbc:mysql://47.118.76.192:3306/ry_vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true
        username: root
        password: Shen1992#
      # 从库数据源
      slave:
        # 从数据源开关/默认关闭
        enabled: false
        url:
        username:
        password:
      # 初始连接数
      initialSize: 5
      # 最小连接池数量
@@ -35,6 +41,8 @@
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      # 注意这个值和druid原生不一致,默认启动了stat
      filters: stat
      webStatFilter:
        enabled: true
      statViewServlet:
@@ -58,13 +66,13 @@
  # redis 配置
  redis:
    # 地址
    host: 47.118.76.192
    host: localhost
    # 端口,默认为6379
    port: 6379
    # 数据库索引
    database: 0
    # 密码
    password: "019920212"
    password:
    # 连接超时时间
    timeout: 10s
    # 是否开启ssl
ruoyi-admin/src/main/resources/application.yml
@@ -15,7 +15,7 @@
captcha:
  # 验证码开关
  enabled: false
  enabled: true
  # 验证码类型 math 数组计算 char 字符验证
  type: math
  # line 线段干扰 circle 圆圈干扰 shear 扭曲干扰
@@ -256,6 +256,13 @@
  circuitbreaker:
    enabled: true
--- # 分布式锁 lock4j 全局配置
lock4j:
  # 获取分布式锁超时时间,默认为 3000 毫秒
  acquire-timeout: 3000
  # 分布式锁的超时时间,默认为 30 毫秒
  expire: 30000
--- # 定时任务配置
spring:
  quartz:
ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java
@@ -1,14 +1,18 @@
package com.ruoyi.demo.controller;
import com.baomidou.lock.LockInfo;
import com.baomidou.lock.LockTemplate;
import com.baomidou.lock.annotation.Lock4j;
import com.baomidou.lock.executor.RedissonLockExecutor;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisLockManager;
import com.ruoyi.demo.service.ITestDemoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalTime;
/**
@@ -22,27 +26,48 @@
public class RedisLockController {
    @Autowired
    private ITestDemoService testDemoService;
    private LockTemplate lockTemplate;
    /**
     * 测试lock4j
     * @param key
     * @param value
     * @return
     * 测试lock4j 注解
     */
    @Lock4j(keys = {"#key"})
    @GetMapping("/testLock4j")
    public  AjaxResult<String> testLock4j(String key,String value){
        testDemoService.testLock4j(key);
        System.out.println("start:"+key+",time:"+ LocalTime.now().toString());
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("end :"+key+",time:"+LocalTime.now().toString());
        return AjaxResult.success("操作成功",value);
    }
    /**
     * 测试lock4j 工具
     */
    @GetMapping("/testLock4jLockTemaplate")
    public  AjaxResult<String> testLock4jLockTemaplate(String key,String value){
        testDemoService.testLock4jLockTemaplate(key);
        final LockInfo lockInfo = lockTemplate.lock(key, 30000L, 5000L, RedissonLockExecutor.class);
        if (null == lockInfo) {
            throw new RuntimeException("业务处理中,请稍后再试");
        }
        // 获取锁成功,处理业务
        try {
            try {
                Thread.sleep(8000);
            } catch (InterruptedException e) {
                //
            }
            System.out.println("执行简单方法1 , 当前线程:" + Thread.currentThread().getName());
        } finally {
            //释放锁
            lockTemplate.releaseLock(lockInfo);
        }
        //结束
        return AjaxResult.success("操作成功",value);
    }
    /**
     * 测试spring-cache注解
ruoyi-demo/src/main/java/com/ruoyi/demo/service/ITestDemoService.java
@@ -19,10 +19,6 @@
 */
public interface ITestDemoService extends IServicePlus<TestDemo> {
    void testLock4j(String key);
    void testLock4jLockTemaplate(String key);
    /**
     * 查询单个
     * @return
ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestDemoServiceImpl.java
@@ -2,18 +2,12 @@
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.lock.LockInfo;
import com.baomidou.lock.LockTemplate;
import com.baomidou.lock.annotation.Lock4j;
import com.baomidou.lock.executor.RedissonLockExecutor;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
import com.ruoyi.common.core.page.PagePlus;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.DataSourceType;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.demo.bo.TestDemoAddBo;
import com.ruoyi.demo.bo.TestDemoEditBo;
@@ -22,10 +16,8 @@
import com.ruoyi.demo.mapper.TestDemoMapper;
import com.ruoyi.demo.service.ITestDemoService;
import com.ruoyi.demo.vo.TestDemoVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalTime;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -38,43 +30,6 @@
 */
@Service
public class TestDemoServiceImpl extends ServicePlusImpl<TestDemoMapper, TestDemo> implements ITestDemoService {
    @Autowired
    private LockTemplate lockTemplate;
    @Override
    public void testLock4jLockTemaplate(String key) {
        final LockInfo lockInfo = lockTemplate.lock(key, 30000L, 5000L, RedissonLockExecutor.class);
        if (null == lockInfo) {
            throw new RuntimeException("业务处理中,请稍后再试");
        }
        // 获取锁成功,处理业务
        try {
            try {
                Thread.sleep(8000);
            } catch (InterruptedException e) {
                //
            }
         System.out.println("执行简单方法1 , 当前线程:" + Thread.currentThread().getName());
        } finally {
            //释放锁
            lockTemplate.releaseLock(lockInfo);
        }
        //结束
    }
    @Override
    @Lock4j(executor = RedissonLockExecutor.class,keys = {"#key"})
    public void testLock4j(String key) {
        System.out.println("start:"+key+",time:"+LocalTime.now().toString());
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("end :"+key+",time:"+LocalTime.now().toString());
    }
    @Override
    public TestDemoVo queryById(Long id) {