spring boot:用redis+redisson实现分布式锁(redisson3.11.1/spring boot 2.2)
一,为什么要使用分布式锁?
说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectforest
对应的源码可以访问这里获取: https://github.com/liuhongdi/
说明:作者:刘宏缔 邮箱: 371125307@qq.com
二,使用redisson
https://redisson.org/
https://github.com/redisson/redisson/wiki
三,演示项目的相关信息
https://github.com/liuhongdi/distributedlock

CREATE TABLE `goods` (
`goods_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
`goods_name` varchar(500) NOT NULL DEFAULT '' COMMENT 'name',
`stock` int(11) NOT NULL DEFAULT '0' COMMENT 'stock',
PRIMARY KEY (`goods_id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='商品表'
四,java代码的说明
@Service
public class OrderServiceImpl implements OrderService { @Resource
private RedissonClient redissonClient;
@Resource
private GoodsMapper goodsMapper; /*
* 加锁减库存
* */
@Override
public boolean decrementProductStoreLock(int goodsId, int buyNum) {
String key = "dec_store_lock_" + goodsId;
//生成锁对象
RLock lock = redissonClient.getLock(key);
try {
//2, TimeUnit.MINUTES
lock.lock(2, TimeUnit.MINUTES);
boolean upRes = updateGoodsStock(goodsId, buyNum);
if (upRes == false) {
return false;
}
} catch (Exception e) {
System.out.println(e.getMessage());
return false;
} finally {
//解锁
if (lock.isHeldByCurrentThread()){
System.out.println("----------------release lock");
lock.unlock();
}
}
return true;
} /*
* 减库存
* */
@Transactional(isolation = Isolation.REPEATABLE_READ)
public boolean updateGoodsStock(int goodsId, int buyNum) {
Goods goodsOne = goodsMapper.selectOneGoods(goodsId);
System.out.println("-------------------------当前库存:"+goodsOne.getStock()+"-------购买数量:"+buyNum);
if (goodsOne.getStock() < buyNum || goodsOne.getStock() <= 0) {
System.out.println("------------------------fail:buy fail,return");
return false;
}
int upStock = goodsOne.getStock()-buyNum;
goodsOne.setStock(upStock);
int upNum = goodsMapper.updateOneGoodsStock(goodsOne);
System.out.println("-------------------------success:成交订单数量:"+upNum);
return true;
} /*
* 不加锁减库存
* */
@Override
public boolean decrementProductStoreNoLock(int goodsId, int buyNum) {
return updateGoodsStock(goodsId, buyNum);
}
}
五,测试高并发时加锁的效果:
mysql> update goods set stock=3;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from goods;
+----------+------------+-------+
| goods_id | goods_name | stock |
+----------+------------+-------+
| 3 | green cup2 | 3 |
+----------+------------+-------+
1 row in set (0.00 sec)
我们设置商品的库存数为3
[root@localhost ~]# ab -c 20 -n 20 http://127.0.0.1:8080/lock/buynolock
查看代码的打印输出:
-------------------------当前库存:3-------购买数量:1
-------------------------success:成交订单数量:1
-------------------------当前库存:2-------购买数量:1
-------------------------success:成交订单数量:1
-------------------------当前库存:1-------购买数量:1
-------------------------当前库存:1-------购买数量:1
-------------------------当前库存:1-------购买数量:1
-------------------------success:成交订单数量:1
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
-------------------------success:成交订单数量:1
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
-------------------------success:成交订单数量:1
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
[root@localhost ~]# ab -c 20 -n 20 http://127.0.0.1:8080/lock/buylock
查看代码的打印输出:
-------------------------当前库存:3-------购买数量:1
-------------------------success:成交订单数量:1
-------------------------当前库存:2-------购买数量:1
-------------------------success:成交订单数量:1
-------------------------当前库存:1-------购买数量:1
-------------------------success:成交订单数量:1
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
-------------------------当前库存:0-------购买数量:1
------------------------fail:buy fail,return
只成功了3个订单,说明分布式锁有效
六,查看spring boot的版本:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.0.RELEASE)
spring boot:用redis+redisson实现分布式锁(redisson3.11.1/spring boot 2.2)的更多相关文章
- 使用Redisson实现分布式锁,Spring AOP简化之
源码 Redisson概述 Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid).它不仅提供了一系列的分布式的Java常用对象,还提供了许多 ...
- Redisson实现分布式锁
转: Redisson实现分布式锁 Redisson文档参考:https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95 redis是实现 ...
- 利用Redisson实现分布式锁及其底层原理解析
Redis介绍 参考地址:https://blog.csdn.net/turbo_zone/article/details/83422215 redis是一个key-value存储系统.和Memcac ...
- Springboot中使用Redisson实现分布式锁
1. 概述 老话说的好:便宜没好货,有价值的商品,即使再贵,也有人会买. 言归正传,今天继续讨论有关"锁"的话题,synchronized 和 ReentrantLock 大家应该 ...
- redis客户端、分布式锁及数据一致性
Redis Java客户端有很多的开源产品比如Redission.Jedis.lettuce等. Jedis是Redis的Java实现的客户端,其API提供了比较全面的Redis命令的支持:Redis ...
- Redis系列(二)--分布式锁、分布式ID简单实现及思路
分布式锁: Redis可以实现分布式锁,只是讨论Redis的实现思路,而真的实现分布式锁,Zookeeper更加可靠 为什么使用分布式锁: 单机环境下只存在多线程,通过同步操作就可以实现对并发环境的安 ...
- Redisson实现分布式锁(3)—项目落地实现
Redisson实现分布式锁(3)-项目落地实现 有关Redisson实现分布式锁前面写了两篇博客作为该项目落地的铺垫. 1.Redisson实现分布式锁(1)---原理 2.Redisson实现分布 ...
- Redisson实现分布式锁(2)—RedissonLock
Redisson实现分布式锁(2)-RedissonLock 有关Redisson实现分布式锁上一篇博客讲了分布式的锁原理:Redisson实现分布式锁---原理 这篇主要讲RedissonLock和 ...
- Redisson实现分布式锁(1)---原理
Redisson实现分布式锁(1)---原理 有关Redisson作为实现分布式锁,总的分3大模块来讲. 1.Redisson实现分布式锁原理 2.Redisson实现分布式锁的源码解析 3.Redi ...
随机推荐
- 吴恩达《深度学习》-第三门课 结构化机器学习项目(Structuring Machine Learning Projects)-第一周 机器学习(ML)策略(1)(ML strategy(1))-课程笔记
第一周 机器学习(ML)策略(1)(ML strategy(1)) 1.1 为什么是 ML 策略?(Why ML Strategy?) 希望在这门课程中,可以教给一些策略,一些分析机器学习问题的方法, ...
- [LeetCode] 279. 完全平方数(DP)
###题目 给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...)使得它们的和等于 n.你需要让组成和的完全平方数的个数最少. 示例 1: 输入: n = 12 输出: 3 解 ...
- 并发编程中死锁、递归锁、进程/线程池、协程TCP服务器并发等知识点
1.死锁 定义; 类似两个人分别被囚禁在两间房子里,A手上拿着的是B囚禁房间的钥匙,而B拿着A的钥匙,两个人都没法出去,没法给对方开锁,进而造成死锁现象.具体例子代码如下: # -*-coding:u ...
- Node.js 从零开发 web server博客项目[接口]
web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...
- input输入框 只能输入数字 oninput = "value=value.replace(/[^\d]/g,'')" input输入框输入大于0的数字 oninput="value=value.replace(/\D|^0/g,'')"
项目中因为利用 element-ui 和avue两个ui框架搭建的 1.利用element-ui自带的校验需要注意点 prop :rules ref这三个属性 2.利用oninput时间进行校验 ...
- Laravel Model查询结果的3种存储格式内存占用对比
PHP Laravel框架支持Model查询数据后可以有多种方式返回数据,对新手会造成一些困扰,比如数组Model对象.集合.纯数组 今天从内存占用的角度对比一下3种数据返回方式 按数组Model对象 ...
- HTML你好!
初识HTML 什么是HTML web的本意是蜘蛛网和网的意思,在网页设计中我们称为网页的意思.现广泛译作网络.互联网等技术领域.表现为三种形式,即超文本(hypertext).超媒体(hypermed ...
- Spring及tomcat初始化日志
Tomcat StandardContext初始化过程 //org.apache.catalina.core.StandardContext#startInternal // 子容器启动 for (C ...
- 推荐条+fragment
主布局 package com.example.dell.day1215; import android.support.design.widget.TabLayout; import android ...
- Node.js文件上传
Node.js express使用Multer实现文件上传html部分 <div> <h3>文件上传:</h3> 选择一个文件上传: <br/> < ...