为了防止用户在页面上重复点击或者同时发起多次请求,请求处理需要操作redis缓存,这个时候需要对并发边界进行并发锁控制,实现思路:

由于每个页面发起的请求带的token具备唯一性,可以将token作为锁(key),当前时间作为value进行并发锁控制,分为两个方法:acquireLock和realeaseLock

/**尝试获取锁并设置有效时间*/
53
+ public boolean acquireLock(String lock, long expired){
54
+ boolean isSuccess = false;
55
+ Jedis jedis = jedisPool.getResource();
56
+ long value = System.currentTimeMillis() + expired + 1;
57
+ long acquired = jedis.setnx(lock, String.valueOf(value));
58
+ if (acquired == 1)
59
+ isSuccess = true;
60
+ else {
61
+ long oldValue = Long.valueOf(jedis.get(lock));
62
+ //如果其他资源之前获得锁已经超时
63
+ if (oldValue < System.currentTimeMillis()){
64
+ String getValue = jedis.getSet(lock, String.valueOf(value));
65
+ if (Long.valueOf(getValue) == oldValue)
66
+ isSuccess = true;
67
+ else
68
+ isSuccess = false;
69
+ }
70
+ else isSuccess = false;
71
+ }
72
+ jedisPool.returnResource(jedis);
73
+ return isSuccess;
74
+ }
75
+
76
+ /**释放锁资源*/
77
+ public void releaseLock(String lock){
78
+ Jedis jedis = jedisPool.getResource();
79
+ long currentTime = System.currentTimeMillis();
80
+ if (currentTime < Long.valueOf(jedis.get(lock))){
81
+ jedis.del(lock);
82
+ }
83
+ jedisPool.returnResource(jedis);
84
+ }

经过代码review,对照开源的jedisLock源码,发现以上实现逻辑问题在于,对于jedisPool.getResource如果发生异常,没有对异常进行处理,在外面包装类加上如下处理:

Object runTask(Callback callback) {
Jedis jedis = null;
boolean broken = false;
try {
jedis = jedisPool.getResource();
return callback.onTask(jedis);
} catch (JedisException e) {
broken = handleJedisException(e);
} catch (Exception e) {
log.error("Redis runTask error: ", e);
} finally {
closeResource(jedis, broken);
jedis = null;
}
return null;
}
private boolean handleJedisException(JedisException jedisException) {
if (jedisException instanceof JedisConnectionException) {
log.error("Redis connection lost.", jedisException);
} else if (jedisException instanceof JedisDataException) {
if ((jedisException.getMessage() != null) && (jedisException.getMessage().indexOf("READONLY") != -1)) {
log.error("Redis connection are read-only slave.", jedisException);
} else {
// dataException, isBroken=false
return false;
}
} else {
log.error("Jedis exception happen.", jedisException);
}
return true;
}
private void closeResource(Jedis jedis, boolean conectionBroken) {
try {
if (conectionBroken) {
jedisPool.returnBrokenResource(jedis);
} else {
jedisPool.returnResource(jedis);
}
} catch (Exception e) {
log.error("return back jedis failed, will fore close the jedis.", e);
jedis.close();
}
}

Redis并发锁控制的更多相关文章

  1. 基于redis实现锁控制

    多数据源 数据源1为锁控制,数据源2自定义,可用于存储. 锁:当出现并发的时候为了保证数据的一致性,不会出现并发问题,假设,用户1修改一条信息,用户2也同时修改,会按照顺序覆盖自修改的值,为了避免这种

  2. Redis修改数据多线程并发—Redis并发锁

    本文版权归博客园和作者本人吴双共同所有 .转载爬虫请注明地址,博客园蜗牛 http://www.cnblogs.com/tdws/p/5712835.html 蜗牛Redis系列文章目录http:// ...

  3. Redis学习笔记~Redis并发锁机制

    回到目录 redis客户端驱动有很多,如ServiceStack.Redis,StackExchange.Redis等等,下面我使用ServiceStack.Redis为例,介绍一下在redis驱动中 ...

  4. redis并发锁

    1.应对并发场景 避免操作数据不一致 将对redis加锁 2.考虑到异常状况无法释放锁,导致死锁 将代码块进行try-catch处理 3.考虑try时宕机依然导致死锁 对锁添加时效性,添加过期时间 4 ...

  5. 使用Redis构建全局并发锁

    谈起Redis的用途,小伙伴们都会说使用它作为缓存,目前很多公司都用Redis作为缓存,但是使用Redis仅仅作为缓存未免太大材小用了.深究Redis的原理后你会发现它有很多用途,在很多场景下能够使用 ...

  6. Redis构建全局并发锁

    Redis构建全局并发锁 https://www.cnblogs.com/FG123/p/9990336.html 谈起Redis的用途,小伙伴们都会说使用它作为缓存,目前很多公司都用Redis作为缓 ...

  7. 【redis】基于redis实现分布式并发锁

    基于redis实现分布式并发锁(注解实现) 说明 前提, 应用服务是分布式或多服务, 而这些"多"有共同的"redis"; (2017-12-04) 笑哭, 写 ...

  8. 用压测模拟并发、并发处理(synchronized,redis分布式锁)

    使用工具:Apache an 测压命令: ab -n 100 -c 100 http://www.baidu.com -n代表模拟100个请求,-c代表模拟100个并发,相当于100个人同时访问 ab ...

  9. 使用Redis分布式锁处理并发,解决超卖问题

    一.使用Apache ab模拟并发压测 1.压测工具介绍 $ ab -n 100 -c 100 http://www.baidu.com/ -n表示发出100个请求,-c模拟100个并发,相当是100 ...

随机推荐

  1. js创建节点及其属性

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  2. XML特殊符号

    在XML中"<" 字符和"&"字符是严格禁止使用的.要使用这几种字符需要使用它们的实体, 下面是五个在XML文档中预定义好的实体:< < ...

  3. .NET WebBroswer内存释放

    最近写的小说爬取工具遇到了性能瓶颈,使用多个Webbroswer控件预加载多个网页,内存会不断增加,达到400M左右,不能忍. 失败的例子 首先尝试把Webbroswer对象置为null,wb=nul ...

  4. Lua热更系统

    1.介绍 使用脚本开发游戏业务逻辑其中一个好处就是代码可线上热更,不停机修复bug.而热更代码的写法与需要被热更的文件的代码又有着密切的关系,本文介绍一种热更方法. 2.热更原理 Lua提供一个叫re ...

  5. js 求点到直线的距离(由2点确定的直线,求到第三点的距离)

    需要用到2个数学公式 1,已知2点求其直线方程 2,点到直线的距离 1,Y=kX+b 分别将两点带入以上方程,求出k 和b 例如: p0={x:?,y:?}, p1={x:?,y:?} 可解得方程: ...

  6. Linux 内核编译

    注:该文章部分内容摘录自以下链接. http://www.cnblogs.com/zhunian/archive/2012/04/04/2431883.html 创建内核的第一步是创建一个 .conf ...

  7. js this理解

    原文链接:http://www.ruanyifeng.com/blog/2010/04/using_this_keyword_in_javascript.html this是js语言的几个关键字,代表 ...

  8. NFC

    NFC手机是指带有NFC模块的手机.带有NFC模块的手机可以做很多相应的应用.NFC是Near Field Communication缩写,即近距离无线通讯技术.在13.56MHz频率运行于20厘米距 ...

  9. BZOJ4247挂饰

    Description     JOI君有N个装在手机上的挂饰,编号为1...N. JOI君可以将其中的一些装在手机上.     JOI君的挂饰有一些与众不同--其中的一些挂饰附有可以挂其他挂件的挂钩 ...

  10. Excel数据批量导入到数据库2

    1.导包(共3个) 2.jsp <s:form action="ReadExcel.action" method="post" enctype=" ...