redis分布式锁和lua脚本

业务场景:多个线程对共同资源的访问:库存超卖/用户重复下单的原因

解决方法一:利用jvm内置锁,将非原子性操作变成原子性操作

Synchronized锁的是对象,对象必须是单例的。锁的是this,代表当前所在的类,这个类是交给Spring 管理的。所有以是单例模式的,所以可以锁住

为什么在分布式项目中不使用synorchronized同步锁:

因为jvm的synorchonized只能保证自己的服务,在集群部署的时候有多个服务,锁不住jvm服务。jvm的内置锁只能解决单体式项目中的并发问题,但是在分布式环境下,无法解决多jvm实例的并发。

分布式锁的实现

分布式事务锁的要素

  1. 锁哪个对象 => 锁指定场次下的指定商品
  2. 当多线程同时加锁时,只能有一个线程加锁成功=>Redis的setnx命令。例如使用setnx秒杀场次+秒杀商品id
  3. 锁记录在什么地方 => 利用redis的setnx命令存储在Redis的String数据结构中
  4. 当线程获取不到锁的时候,执行什么策略 => 阻塞/自旋等待(限制次数)/直接抛异常

Finally 释放锁

这么写会造成锁的问题

如果加完redis的key以后程序挂了,那么这个key就释放不了,就会一直在里面,会造成死锁:解决方式------设置超时时间

但是存键值和设置超时时间是两个操作,不是一个完整的原子性操作

利用LUA脚本进行操作,定义加载lua脚本的配置

在resource下面新建lua脚本

在代码中执行lua脚本保证命令的原子性

相关推荐
代码不停3 分钟前
MyBatis操作数据库
数据库·mybatis
程序猿乐锅4 分钟前
面向对象练习:图书借阅系统里的封装、抽象类与多态
开发语言·前端·数据库·后端·python·学习·1024程序员节
我不会起名字32211 分钟前
Redis 从 0 到 1(十二):先删缓存还是先更新库?4 种方案的 Go 并发实测
redis·go·并发·延迟双删·缓存一致性
严同学正在努力14 分钟前
PostgreSQL 高可用教程(流复制 + Patroni 生产级实战)
运维·数据库·ai·postgresql·架构
牧瀬クリスだ17 分钟前
Redis String深度解析:从底层到五大实战场景
数据库·redis·缓存
利威尔xu29 分钟前
Go IM 源码实战(7):断线三天重连,水位算错就漏消息
redis·后端·微服务·面试·golang
Random Glow41 分钟前
聚簇索引:为什么主键顺序决定插入性能
数据库·mysql·性能优化·innodb·索引
软件技术NINI43 分钟前
基于PHP和MySQL的快递代收点管理系统的设计与实现
开发语言·javascript·数据库·mysql·毕业设计·php·毕设
吹什么轩1 小时前
MySQL 增删改查(CRUD)完全指南:从 INSERT 到 GROUP BY
数据库·mysql
T量子永生1 小时前
Android SISO 分布式编译集群配置方案
android·分布式·云计算·源代码管理