美文网首页SpringBoot学习
054-Redis分布式锁

054-Redis分布式锁

作者: 郭艺宾 | 来源:发表于2018-10-31 00:30 被阅读4次

在工作过程中,在同时操作数据库的时候,出现了相同数据插入多条的情况,针对这个问题,我能想到可以有如下几种解决方法:

加悲观锁

在方法前加锁(synchronized关键字),或者在方法里面加锁。但考虑到在集群情况下,依然可能存在问题,故没有采用该方案。

唯一约束

可以给数据库的表中的字段加上唯一约束,这样到执行insert语句时,当发现数据库中已经存在该记录,就会抛出异常!但有的DBA规定不能给字段加唯一约束,所以该方案有时候并不可用。

加分布式锁

由于项目中基本都使用了Redis,所以直接用Redis实现分布式锁。命令 

SET  key  value  NX EX max-lock-time 

是一种在 Redis 中实现锁的简单方法。客户端执行以上的命令:

如果服务器返回 OK ,那么这个客户端获得锁。

如果服务器返回 NIL ,那么客户端获取锁失败,可以在稍后再重试。

设置的过期时间到达之后,锁将自动释放。可以通过以下修改,让这个锁实现更健壮:

不使用固定的字符串作为键的值,而是设置一个不可猜测(non-guessable)的长随机字符串,作为口令串(token)。

不使用 DEL 命令来释放锁,而是发送一个 Lua 脚本,这个脚本只在客户端传入的值和键的口令串相匹配时,才对键进行删除。

这两个改动可以防止持有过期锁的客户端误删现有锁的情况出现。以下是一个简单的解锁脚本示例:

这个脚本可以通过 EVAL ...script... 1 resource-name token-value 命令来调用。

下面看一下代码中的获取和解锁方法:

下面的代码执行了获取锁:

上面使用的是springboot的1.5.10版本,connection.set方法返回类型为void,所以判断是否获取锁成功要根据键值判断一次,这种使用方式对值要求每次都不一样,最好是使用通过发号器生成的唯一id。

从2版本开始,connection.set方法返回类型变为 Boolean ,

如果使用redis分布式锁,建议使用springboot2以上的版本。

下面的代码执行了解锁:

可以看到解锁方法正是执行了lua脚本的内容。

2版本例子测试如下:

再次获取锁失败:

解锁:

再次解锁失败:

代码:https://gitee.com/blueses/spring-boot-demo

相关文章

  • 054-Redis分布式锁

    在工作过程中,在同时操作数据库的时候,出现了相同数据插入多条的情况,针对这个问题,我能想到可以有如下几种解决方法:...

  • 分布式锁

    为什么要用分布式锁 数据库乐观锁redis分布式锁zookeeper分布式锁 使用分布式锁的场景 实现分布式锁的方...

  • 什么是分布式锁?几种分布式锁分别是怎么实现的?

    一、什么是分布式锁: 1、什么是分布式锁: 分布式锁,即分布式系统中的锁。在单体应用中我们通过锁解决的是控制共享资...

  • 4:Redis 分布式锁 (文末有项目连接)

    1:什么是缓存分布式锁 2:分布式锁的关键代码 3:业务代码使用分布式缓存锁 4:业务代码使用分布式缓存锁 5:测...

  • 锁(2)-- 分布式锁

    前言: 锁分3种:java锁、分布式锁、DB锁 分布式锁的几种实现方式 目前几乎很多大型网站及应用都是分布式部署...

  • java锁的概念

    参考文档探究分布式并发锁并发编程-锁的发展和主流分布式锁比较总结从构建分布式秒杀系统聊聊分布式锁探索并发编程(六)...

  • Redis实现分布式锁

    分布式下的分布式锁一般实现有三种: 基于数据库的乐观锁 基于redis的分布式锁 基于zookeeper的分布式锁...

  • 分布式锁

    为什么要用分布式锁? 分布式锁是悲观锁的实现; 如果采用乐观锁的方案就用不着分布式锁了。 能用乐观锁的地方尽量用乐...

  • 3.10:分布式锁

    本文将梳理微服务架构下,分布式锁的常用方案。整体包含以下三部分: 分布式锁的提出 分布式锁主流方案 分布式锁选择 ...

  • Redis实现分布式锁

    1. 分布式锁分类 数据库乐观锁 基于Redis的分布式锁 基于ZooKeeper的分布式锁 2. 组件依赖 po...

网友评论

    本文标题:054-Redis分布式锁

    本文链接:https://www.haomeiwen.com/subject/vbcotqtx.html