当前位置: 首页 > news >正文

Redis的并发竞争问题的解决方案总结

什么是Redis的并发竞争问题

Redis的并发竞争问题,主要是发生在并发写竞争。

考虑到redis没有像db中的sql语句,update val = val + 10 where ...,无法使用这种方式进行对数据的更新。

假如有某个key = "price",  value值为10,现在想把value值进行+10操作。正常逻辑下,就是先把数据key为price的值读回来,加上10,再把值给设置回去。如果只有一个连接的情况下,这种方式没有问题,可以工作得很好,但如果有两个连接时,两个连接同时想对还price进行+10操作,就可能会出现问题了。

例如:两个连接同时对price进行写操作,同时加10,最终结果我们知道,应该为30才是正确。

考虑到一种情况:

T1时刻,连接1将price读出,目标设置的数据为10+10 = 20。

T2时刻,连接2也将数据读出,也是为10,目标设置为20。

T3时刻,连接1将price设置为20。

T4时刻,连接2也将price设置为20,则最终结果是一个错误值20。

解决方案

方案1

利用redis自带的incr命令,具体用法看这里http://doc.redisfans.com/string/incr.html。

方案2

可以使用独占锁的方式,类似操作系统的mutex机制。(网上有例子,http://blog.csdn.net/black_ox/article/details/48972085 不过实现相对复杂,成本较高)

方案3

使用乐观锁的方式进行解决(成本较低,非阻塞,性能较高)

如何用乐观锁方式进行解决?

本质上是假设不会进行冲突,使用redis的命令watch进行构造条件。伪代码如下:

watch price

get price $price

$price = $price + 10

multi

set price $price

exec

解释一下:

watch这里表示监控该key值,后面的事务是有条件的执行,如果从watch的exec语句执行时,watch的key对应的value值被修改了,则事务不会执行。

具体看Redis的事务功能详解这篇文章里的watch命令介绍。

方案4

这个是针对客户端来的,在代码里要对redis操作的时候,针对同一key的资源,就先进行加锁(java里的synchronized或lock)。

方案5

利用redis的setnx实现内置的锁。

相关文章:

  • Linux 更换成阿里云的源 yum
  • 将打开的网页以html格式下载到本地
  • wxPython,线程中修改UI的方法
  • 交叉熵代价函数——当我们用sigmoid函数作为神经元的激活函数时,最好使用交叉熵代价函数来替代方差代价函数,以避免训练过程太慢...
  • nxn随机矩阵乘以概率向量依旧是概率向量
  • Yii2 如何关闭debug
  • 渗透测试流程
  • MapReduce数据筛选
  • free()
  • 【转载】TCP协议要点和难点全解
  • 技术开发人员也得有点儿傍身的大数据技能!
  • odoo开发笔记--odoo可用小图标
  • mysql修改表、字段、库的字符集
  • node.js中的流
  • realm vs. domain
  • JS中 map, filter, some, every, forEach, for in, for of 用法总结
  • [deviceone开发]-do_Webview的基本示例
  • ➹使用webpack配置多页面应用(MPA)
  • dva中组件的懒加载
  • jquery ajax学习笔记
  • MySQL的数据类型
  • sessionStorage和localStorage
  • storm drpc实例
  • uva 10370 Above Average
  • vue-router的history模式发布配置
  • 工作手记之html2canvas使用概述
  • 如何借助 NoSQL 提高 JPA 应用性能
  • 深度学习入门:10门免费线上课程推荐
  • 思否第一天
  • 携程小程序初体验
  • 延迟脚本的方式
  • 以太坊客户端Geth命令参数详解
  • $ git push -u origin master 推送到远程库出错
  • (C语言)fgets与fputs函数详解
  • (env: Windows,mp,1.06.2308310; lib: 3.2.4) uniapp微信小程序
  • (PyTorch)TCN和RNN/LSTM/GRU结合实现时间序列预测
  • (Repost) Getting Genode with TrustZone on the i.MX
  • (八)Docker网络跨主机通讯vxlan和vlan
  • (仿QQ聊天消息列表加载)wp7 listbox 列表项逐一加载的一种实现方式,以及加入渐显动画...
  • (三维重建学习)已有位姿放入colmap和3D Gaussian Splatting训练
  • (十八)SpringBoot之发送QQ邮件
  • (十二)python网络爬虫(理论+实战)——实战:使用BeautfulSoup解析baidu热搜新闻数据
  • (算法)Game
  • (一)spring cloud微服务分布式云架构 - Spring Cloud简介
  • ./configure,make,make install的作用(转)
  • .bat文件调用java类的main方法
  • .Net core 6.0 升8.0
  • .NET 跨平台图形库 SkiaSharp 基础应用
  • .net 桌面开发 运行一阵子就自动关闭_聊城旋转门家用价格大约是多少,全自动旋转门,期待合作...
  • .NET大文件上传知识整理
  • .NET设计模式(7):创建型模式专题总结(Creational Pattern)
  • .NET是什么
  • /deep/和 >>>以及 ::v-deep 三者的区别
  • /proc/stat文件详解(翻译)
  • @拔赤:Web前端开发十日谈