redis锁处理并发问题
redis锁处理并发问题
redis锁处理高并发问题十分常见,使用的时候常见有几种错误,和对应的解决办法。
- set方式
- setnx方式
- setnx+getset方式
set方式
加锁:redis中set一个值,set(lock,1);
并发处理:其他线程必须拿到这个值,才可以往下进行,否则等待。
while(jedis.exists(lock)){
Thread.sleep(500);
}
set(lock,1);
执行业务代码;
jedis.del(lock);
释放锁:执行完业务代码之后,释放redis锁,jedis.del(lock)
防止死锁:set(lock,1) —>3秒后未释放,则自动释放setex(lock, 3, 1)
问题:高并发情况下,进程同时获取锁状态为null,同时设置,锁之间相互覆盖,但是俩进程仍在并发执行业务代码。
setnx方式
后来发现有setnx的原子操作命令,锁存在不能设置值,返回0;锁不存在,则设置锁,返回1;
加锁:jedis.setnx(lock, 1)
并发处理:
while(jedis.setnx(lock,1)==0){
Thread.sleep(300);
}
执行业务代码;
jedis.del(lock);
释放锁:执行完业务代码之后,释放redis锁,jedis.del(lock)
问题:当进程执行出现问题,锁未释放,则其他进程永远处于阻塞状态,出现死锁。
防止死锁:加锁时带上时间戳,setnx(lock, 时间戳+超时时间)
while(jedis.setnx(lock,now+超时时间)==0){
if(jedis.get(lock)<now){
jedis.del(lock);
jedis.setnx(lock,now+超时时间);
break;
}else{
Thread.sleep(300);
}
}
执行业务代码;
jedis.del(lock);
问题:当俩进程同时读到发现锁超时,都去释放锁,相互覆盖,则俩进程同时获得锁,仍并发执行业务代码。
setnx+getset方式
为解决上面的问题,可以使用getset命令,getset设置键值,并返回原来的键值。
加锁:setnx(lock, 时间戳+超时时间)
解决并发:
while(jedis.setnx(lock, now+超时时间)==0){
if(now>jedis.get(lock) && now>jedis.getset(lock, now+超时时间)){
break;
}else{
Thread.sleep(300);
}
}
执行业务代码;
jedis.del(lock);
释放锁:jedis.del(lock);
redis锁处理并发问题的更多相关文章
- (实例篇)php 使用redis锁限制并发访问类示例
1.并发访问限制问题 对于一些需要限制同一个用户并发访问的场景,如果用户并发请求多次,而服务器处理没有加锁限制,用户则可以多次请求成功. 例如换领优惠券,如果用户同一时间并发提交换领码,在没有加锁限制 ...
- php 使用redis锁限制并发访问类
1.并发访问限制问题 对于一些需要限制同一个用户并发访问的场景,如果用户并发请求多次,而服务器处理没有加锁限制,用户则可以多次请求成功. 例如换领优惠券,如果用户同一时间并发提交换领码,在没有加锁限制 ...
- PHP进阶与redis锁限制并发访问功能示例
<?php /** * Redis锁操作类 * Date: 2017-06-30 * Author: fdipzone * Ver: 1.0 * * Func: * public lock 获取 ...
- redis 初步认识四(redis锁,防并发)
using System; namespace ConsoleAppRedis { class Program { static void Main(string[] args) { //第一种,无登 ...
- 使用Redis构建全局并发锁
谈起Redis的用途,小伙伴们都会说使用它作为缓存,目前很多公司都用Redis作为缓存,但是使用Redis仅仅作为缓存未免太大材小用了.深究Redis的原理后你会发现它有很多用途,在很多场景下能够使用 ...
- 多线程并发问题解决之redis锁
一 问题背景 我们做的是医疗信息化系统,在系统中一条患者信息对医院中当前科室中的所有诊断医生是可见的,当有一个诊断医生点击按钮处理该数据时,数据的状态发生了变化,其他的医生就不可以再处理此患者的数据了 ...
- Redis构建全局并发锁
Redis构建全局并发锁 https://www.cnblogs.com/FG123/p/9990336.html 谈起Redis的用途,小伙伴们都会说使用它作为缓存,目前很多公司都用Redis作为缓 ...
- 利用Redis锁解决高并发问题
这里我们主要利用Redis的setnx的命令来处理高并发. setnx 有两个参数.第一个参数表示键.第二个参数表示值.如果当前键不存在,那么会插入当前键,将第二个参数做为值.返回 1.如果当前键存在 ...
- 利用 Redis 锁解决高并发问题
这里我们主要利用 Redis 的 setnx 的命令来处理高并发. setnx 有两个参数.第一个参数表示键.第二个参数表示值.如果当前键不存在,那么会插入当前键,将第二个参数做为值.返回 1.如果当 ...
随机推荐
- Nginx+Tomcat高性能负载均衡集群搭建
转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/8745794.html Nginx是一个高性能的HTTP服务器/反向代理服务器及电子邮件(IMAP/POP3) ...
- 新概念英语(1-63)Thank you, doctor.
新概念英语(1-63)Thank you, doctor. Who else is in bed today? why? A:How's Jimmy today? B:Better. Thank yo ...
- Spring Security 入门(1-5)Spring Security - 匿名认证
匿名认证 对于匿名访问的用户,Spring Security 支持为其建立一个匿名的 AnonymousAuthenticationToken 存放在 SecurityContextHolder 中, ...
- ubuntu 虚拟机上的 django 服务,在外部Windows系统上无法访问
背景介绍 今天尝试着写了一个最简单的django 服务程序,使用虚拟机(Ubuntu16.02 LTS)上的浏览器访问程序没有问题.但是在物理机器上(win10 Home) 就出现错误 解决方法 在 ...
- logback中配置的日志文件的生成地址
配置文件如下 <?xml version="1.0" encoding="UTF-8"?> <configuration debug=&quo ...
- 基于哈夫曼编码的文件压缩(c++版)
本博客由Rcchio原创 我了解到很多压缩文件的程序是基于哈夫曼编码来实现的,所以产生了自己用哈夫曼编码写一个压缩软件的想法,经过查阅资料和自己的思考,我用c++语言写出了该程序,并通过这篇文章来记录 ...
- web框架之Flask
Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后 ...
- Vue项目结构说明
简单介绍目录结构 http://blog.csdn.net/u013778905/article/details/53864289 (别人家的链接,留给我自己看的)
- Multipath在OpenStack中的faulty device的成因及解决(part 1)
| 版权:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接.如有问题,可以邮件:wangxu198709@gmail.com 简介: Multip ...
- Tab标签js切换高效率写法
原来的传统写法: function tabit(id,cid) { for(var i=0; i<10; i++){ gi(["tab"+i]).className = &q ...