redission实现分布式锁(文字少,都是代码)

基于Redis方式实现分布式锁 立即下载

redission实现分布式锁(文字少,都是代码)

redission是最好用的客户端,底层由netty实现,可以说是一个可以操作redis的框架,实现很多功能,包括分布式锁,本章让我们看一下分布式锁怎么实现

1.创建一个springboot工程,导入maven依赖, 创建application.yml并添加配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>redission-code</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.3.2.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>2.3.5.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.redisson/redisson-spring-boot-starter -->
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson-spring-boot-starter</artifactId>
            <version>3.12.5</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.1</version>
        </dependency>
<!--        mysql连接-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.23</version>
        </dependency>
<!--        自动生成代码-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.4.1</version>
        </dependency>
<!--        velocity模板-->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.0</version>
        </dependency>
<!--        swagger-->
        <!--swagger-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <!--swagger ui-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
        <!--swagger-bootstrap-ui-->
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>swagger-bootstrap-ui</artifactId>
            <version>1.9.2</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>

    </dependencies>
</project>
spring:
  profiles:
    active: dev # 环境设置
  application:
    name: service-core # 服务名
  datasource: # mysql数据库连接
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://host:3306/seckill?serverTimezone=GMT%2B8&characterEncoding=utf-8
    username: root
    password: root
  redis:
    host: host
    password: 123456
    database: 0
    port: 6380

#mybatis xml文件地址
#mybatis-plus:
#  configuration:
#    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
#    mapper-locations: classpath:com/levi/mapper/xml/*.xml


redission:
  address: redis://192.168.177.129:6380
  password: 123456

2.数据库建表用于测试,表明 product表结构如下
id,产品名称,库存在这里插入图片描述
3.使用mybatisplus逆向生成工程,代码如下,执行之后生成

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.junit.Test;

/**
 * @ClassName CodeGenerator
 * @Description TODO
 * @Author Levi
 * @Date 2021/4/14 10:41
 **/
public class CodeGenerator {
    @Test
    public void genCode() {

        // 1、创建代码生成器
        AutoGenerator mpg = new AutoGenerator();

        // 2、全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setAuthor("levi");
        gc.setOpen(false); //生成后是否打开资源管理器
        gc.setServiceName("%sService");	//去掉Service接口的首字母I
        gc.setIdType(IdType.AUTO); //主键策略
        gc.setSwagger2(true);//开启Swagger2模式
        mpg.setGlobalConfig(gc);

        // 3、数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://192.168.177.129:3306/seckill?serverTimezone=GMT%2B8&characterEncoding=utf-8");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("St1282001316*");
        dsc.setDbType(DbType.MYSQL);
        mpg.setDataSource(dsc);

        // 4、包配置
        PackageConfig pc = new PackageConfig();
        pc.setParent("com.levi");
        pc.setEntity("pojo"); //此对象与数据库表结构一一对应,通过 DAO 层向上传输数据源对象。
        mpg.setPackageInfo(pc);

        // 5、策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略

        strategy.setColumnNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略
        strategy.setEntityLombokModel(true); // lombok
        strategy.setLogicDeleteFieldName("is_deleted");//逻辑删除字段名
        strategy.setEntityBooleanColumnRemoveIsPrefix(true);//去掉布尔值的is_前缀(确保tinyint(1))
        strategy.setRestControllerStyle(true); //restful api风格控制器
        mpg.setStrategy(strategy);

        // 6、执行
        mpg.execute();
    }
}


4.创建一个service接口,并且实现里面的方法

package com.levi.service;

public interface SecKillService {

    boolean buyProduct(Integer id, Integer quantity) throws Exception;
}
package com.levi.service.impl;

import com.levi.mapper.ProductMapper;
import com.levi.pojo.Product;
import com.levi.service.SeckillService;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

@Service
public class SeckillServiceImpl implements SeckillService {

    @Autowired
    private RedissonClient redissonClient;

    @Resource
    ProductMapper productMapper;

    @Override
    public boolean buyProduct(Integer id, Integer quantity) {
        RLock lock = null;
        try {
            lock = redissonClient.getLock("sec_kill" + id);
//            获得公平锁,先到先得
//            lock = redissonClient.getFairLock("Sec_kill" + id);
            lock.tryLock(2, 5, TimeUnit.SECONDS);
            Product product = productMapper.selectById(id);
            //如果产品的库存为0或者库存数量小于购买数量则返回false
            if (product.getStack() == 0 || product.getStack()<quantity) {
                return false;
            }
            //购买,扣库存
            product.setStack(product.getStack() - quantity);
            productMapper.updateById(product);

        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
        return true;
    }
}

5.创建controller用于测试,每个人只能买一个

package com.levi.controller;

import com.levi.service.SeckillService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Slf4j
@RequestMapping("redission")
public class SeckillController {
    @Autowired
    private SeckillService seckillService;

    @GetMapping("secKill")
    public void secKill() {
        if (!seckillService.buyProduct(1,1)) {
            log.info("{}商品库存不足",Thread.currentThread().getName());
        }else {
            log.info("{}购买商品成功",Thread.currentThread().getName());
        }
    }
}

6.启动类启动

package com.levi;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan(basePackages = {"com.levi.mapper"})
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

7.用jmeter测试 创建10个线程,但是库存只有5个商品,
在这里插入图片描述
在这里插入图片描述
执行结果
在这里插入图片描述
数据库
在这里插入图片描述
最后,redission官网添加链接描述
第一次写文章,有不足之处还望指出 0.0

Java注解如何基于Redission实现分布式锁 主要介绍了Java注解如何基于Redission实现分布式锁,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 立即下载

相关推荐

java实现自动发送微信QQ消息(可发图片)

自动发送微信/QQ/微博等消息 一:功能:实现发送QQ/微信/微博消息,程序控制。 效果演示(实现自动发生QQ微信消息给女友,发微博信息也可以就不演示了) 二:原理讲解:将剪贴板的内容给发送到QQ微信中去,复制粘贴发送。 模拟真实操作进行发送信息。 三:前期准备,软件安装,及初步测试。...

XURUNFA950827的博客 1万+

Redisson实现分布式锁代码实现

Redisson实现分布式锁代码实现

文雯的博客 852

手把手推导APM的 sqrt_controller控制器

前言 玩过无人机的朋友对APM应该都不会陌生,如果是搞过多旋翼飞控且读过代码,肯定遇到过sqrt_controller控制器,它频繁的在位置、姿态控制中出现,所以非常有必要搞清楚这个控制原理。 下面以高度控制器为例来分析。 高度控制 APM的高度控制采用PID串级3环控制,即外环位置控制,中间速度控制,内环速度控制,如下图所示。 今天要讨论的sqrt_controller就是应用于位置控制器中。位置控制器的输出是速度控制器的参考reference输入,如果采用单P控制,其输出vel_ref = pos_e

周小逗的博客 3027

Redission实现分布式锁

1、代码中常见的redis分布式锁 2、redission lock实现,有什么问题,注意事项 3、红锁(redLock),联锁(multiLock)用来解决什么问题,比较 4、看门狗是什么

重点在于记录 2520

UDS $27服务DLL文件生成

UDS 27算法 DLL文件生成

hkj8808的博客 1281

爬取国家统计局最近10年年度数据

一、编码流程 1.目标网址:https://data.stats.gov.cn/easyquery.htm?cn=C01 2.编码思路: (1) 解析左侧指标树,实现4级标签定位 (难点:层层嵌套,下一级指标的xpath路径以上一级指标为基础;不是所有二级指标都含有三和四级指标,需要进行判断) (2) 使用selenium webdriver 点选指标,加载出右侧表格数据 (难点:当指标无法在全局页面显示时,需向下拖动滚动条) (3) 解析右侧数据,实现数据存储 3.使用模块: (1) selenium:解

weixin_39645690的博客 4556

Redission分布式锁

Redisson是一个基于Redis实现的Java分布式对象服务框架,其中提供了丰富的分布式锁实现。本文介绍了Redisson分布式锁的基本原理和使用方法,包括公平锁、联锁、红锁、读写锁、信号量、闭锁等多种类型的锁实现。通过示例代码的演示,读者可以了解每种锁的使用场景和实现方式。Redisson通过基于Redis实现的分布式锁,避免了手动实现分布式锁的复杂性和容错性问题,使用Redisson可以方便地实现各种分布式锁功能,从而提高分布式系统的稳定性和可靠性。

tongshao100的博客 2583

【软考】数据库系统工程师备考指南(一)

目录一、数据库系统工程师简介二、考试要求三、考试目标四、考试范围(一)信息系统知识(二)数据库系统设计与管理 一、数据库系统工程师简介 数据库系统工程师考试属于全国计算机技术与软件专业技术资格(水平)考试(简称计算机软件水平资格考试)中的一个中级考试。考试不设学历与资历条件,也不论年龄和专业,考生可根据自己的技术水平选择合适的级别合适的资格,但一次考试只能报考一种资格。考试采用笔试形式,考试实行全国统一大纲、统一试题、统一时间、统一标准、统一证书的考试办法。笔试安排在一天之内。 2022 年数据库系统工程

邓邓子的博客 3859

【Redis】基于Redisson实现分布式锁(代码实现)

基于Redisson实现分布式锁解决商品秒杀超卖的场景,包含测试代码。

m0_64210833的博客 2543

YOLOv11+BiFPN双向特征金字塔:全方位解析多尺度检测性能优化指南

飞书链接:https://ecn6838atsup.feishu.cn/wiki/EhRtwBe1CiqlSEkHGUwc5AP9nQe?购买即可解锁800+YOLO优化文章,并且还有海量深度学习复现项目,价格仅需两杯奶茶的钱,每日更新。函数中添加BiFPN的解析逻辑(找到。链接可用,不要多复制空格了。密码:946m22&8。

FJN110的博客 306

一张微服务地图的十年演进:Spring Cloud 核心、扩展与工具组件的定位、原理与选型

本文把 Spring Cloud 当作一张微服务地图来读:先说明它是由 Commons 抽象层、实现层和 Boot 装配层构成的发行版,再沿一次请求梳理注册发现、负载均衡、声明式调用、容错限流、网关、配置、追踪与总线七类核心组件的原理与换代,并扩展到云平台、服务网格、消息流、批处理、安全与周边生态。仿真实测:默认参数下实例宕机平均 242 秒才被感知,优雅下线降到 47 秒;一个慢实例让轮询的 P99 达 49 秒,P2C 仅 203 毫秒。最后给出退场替代表、技术栈组合、升级路线和决策树。

曾经“等你生日那天”都遥远得像未来,如今却可欢愉的挥手说“下个十年见” 169万+

Redis(四)——Redis 处理接口幂等性(代码实现、两种方式拦截令牌)、Redis 分布式锁(两种引入 lua 脚本、Redission实现分布式锁)、Redis做限流工具(简单限流,限流插件)

Redis(四)——Redis 处理接口幂等性(代码实现、两种方式拦截令牌)、Redis 分布式锁(两种引入 lua 脚本、通过 Redission 实现分布式锁)、Redis做限流工具(简单限流,限流插件——Redis-Cell模块(使用了漏斗算法)、java 代码操作(使用 Lettuce 扩展))

qq_41824825的博客 2619

科研绘图系列:R语言circos图(circos plot)

科研绘图系列:R语言circos图(circos plot)

专注生信领域 3430

redis分布式锁的各种坑

用redis做分布式锁,看似是一个非常简单的问题,但是其中却蕴含着很多坑,我从单机方式开始把redis分布式锁的所有坑都踩一踩,豁然开朗。文字描述较少,直接上代码,相信大家一看就懂。尤其是点评把每一个情况的坑描述出来了。后一种情况会把上一种情况的坑给解决掉。 第一种情况:单机方式 我们对一个库存进行扣减的一个简单操作 public class RedisService { @Autowi...

qq_36794621的博客 1031

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

redis 分布式锁 看门狗_Redis:分布式锁

熟悉Redis的同学那么肯定对setNx(set if not exist)方法不陌生,如果不存在则更新,其可以很好的用来实现我们的分布式锁。对于某个资源加锁我们只需要1setNx resourceName value这里有个问题,加锁了之后如果机器宕机那么这个锁就不会得到释放所以会加入过期时间,加入过期时间需要和setNx同一个原子操作,在Redis2.8之前我们需要使用Lua脚本达到我们的目的...

weixin_39608526的博客 462

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

分布式锁用Redis还是Zookeeper?

为什么用分布式锁? 系统 A 是一个电商系统,目前是一台机器部署,系统中有一个用户下订单的接口,但是用户下订单之前一定要去检查一下库存,确保库存足够了才会给用户下单。 由于系统有一定的并发,所以会预先将商品的库存保存在 Redis 中,用户下单的时候会更新 Redis 的库存。 此时系统架构如下: 但是这样一来会产生一个问题:假如某个时刻,Redis 里面的某个商品库...

shiyuezhong的专栏 1959

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

分布式锁用 Redis 还是 Zookeeper?

作者:jianfeng来源:石杉的架构笔记为什么用分布式锁?在讨论这个问题之前,我们先来看一个业务场景:系统A是一个电商系统,目前是一台机器部署,系统中有一个用户下订单的接口,但是用户下...

Java知音 205

删除sybase里面的锁_面试不懂分布式锁?那得多吃亏

来源 | 石杉的架构笔记作者 | jianfeng责编 | linse01为什么用分布式锁?在讨论这个问题之前,我们先来看一个业务场景:系统A是一个电商系统,目前是一台机器部署,系统中有一个用户下订单的接口,但是用户下订单之前一定要去检查一下库存,确保库存足够了才会给用户下单。由于系统有一定的并发,所以会预先将商品的库存保存在redis中,用户下单的时候会更新redis的库存。此时系统架...

weixin_39727336的博客 71

分布式锁和分布式事务

线程B 加锁B4 B5成功,没有获取锁。线程A获取锁,返回将锁存放在数据库中,此时JVM stw, 线程b去获取锁,修改锁,与数据库已经存在的锁标识进行对比。A线程获取锁,B线程等待,此时A线程释放锁,程序还未执行完成。此时B线程获取锁,此时A,B都将库存减到9,与业务不符。一主一从,线程A从主机获取锁,此时主宕机,线程B从从机也获取了锁。分布式锁:redis分布式锁, zk分布式锁, 数据库做分布式锁。-----------程序A---------->程序B----->----------

qq_44970261的博客 557

redis中有key但是删不掉_分布式锁用 Redis 还是 Zookeeper

为什么用分布式锁?在讨论这个问题之前,我们先来看一个业务场景:系统A是一个电商系统,目前是一台机器部署,系统中有一个用户下订单的接口,但是用户下订单之前一定要去检查一下库存,确保库存足够了才会给用户下单。由于系统有一定的并发,所以会预先将商品的库存保存在redis中,用户下单的时候会更新redis的库存。此时系统架构如下:但是这样一来会产生一个问题:假如某个时刻,redis里面的某个商品库存为1,...

weixin_42306480的博客 159

java如何保证redis设置过期时间的原子性_分布式锁用 Redis 还是 Zookeeper?

链接;https://mp.weixin.qq.com/s/WF32uapifuVGcRjr4Zfz-Q

weixin_39834678的博客 206

SpringBoot中Redisson锁的使用(代码验证锁的流程)

前段时间自己在研究java中的锁相关的东西,从关键字到JUC中的Lock,这些锁可以在单个JVM中起到很好的作用。之前写过锁相关的文章有:深入理解Java中的synchronized深入理解Java中的Lock和AQSZookeeper 实现分布式锁(java 实现)本文就主要学习一下 Redis 在做分布式锁时,是如何使用的。

FBB360JAVA的博客 1057

细说Redis分布式锁:setnx/redisson/redlock?了解一波?

redis分布式锁,红锁

gb4215287的博客 819

【SpringBoot框架篇】10.API接口限流实战

文章目录简介限流算法漏桶算法令牌桶算法基于guava的RateLimiter实现引入依赖自定义注解自定义切面类编写web接口压测 简介 对接口限流的目的是通过对并发访问/请求进行限速,或者对一个时间窗口内的请求进行限速来保护系统,一旦达到限制速率则可以拒绝服务、排队或等待、降级等处理 限流算法 常用的限流算法由:楼桶算法和令牌桶算法。 漏桶算法 漏桶(Leaky Bucket)算法思路很简单,水(请求)先进入到漏桶里,漏桶以一定的速度出水(接口有响应速率),当水流入速度过大会直接溢出(访问频率超过接口响应速

皓亮君的博客 1万+
下一篇: curator(zookeeper)实现分布式锁简单代码
livel_java
博客等级 码龄9年 2916粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值