博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
redis-乐观锁与事务
阅读量:3985 次
发布时间:2019-05-24

本文共 1128 字,大约阅读时间需要 3 分钟。

一、乐观锁

先表明态度,乐观锁并不是一个好的实现方式!
在mysql中,我们一般通过给数据表额外建一个version字段,读的时候读出verson,更新的时候 v2 = versin+1,语句为

update xxx set xxx=xxx, version = version + 1 where id = xxx and version < v2;

只要有人在我前面更新了,我就会更新失败。然后直接响应给客户端错误吗?显然不能,在大并发的情况下,难道要客户一次次的手动提交吗?所以,我们只能替用户去循环尝试更新,让用户多等待一会,当然要设置循环次数或者时间。而且,虽然更新失败了,但是依然操作了数据库,而且是循环操作,更加使脆弱的mysql雪上加霜。那么,乐观锁能保证数据安全吗?可以的,因为在更新version的时候使用的是自增而不是赋值。

二、redis事务

虽然redis是单线程的,但是使用事务的时候,事务块会被放入事务队列中,直到调用exec命令,此时事务块作为一个原子插入到主执行队列中,虽然在执行事务块的时候是单线程的不存在并发,但是在构成事务块的过程中主线程同时执行着其他命令,是并行的,所以总的来看,事务不能保证数据的安全性。另外,redis事务不具备一致性,没有回滚机制。

示例1:	multi	set name rao	set age 12	set score 100	exec示例2:	multi	set name rao	set age 13	incr name	exec	get age报错但没有回滚处理!!!!

exec返回以个数组,就是所有命令依次的结果。

当在构造事务的过程中想要取消事务,可使用discard命令

三、redis事务加乐观锁

既然存在并行的情况,那么数据安全就没法保障,所以,必须加个锁来保证事务过程中key的值不被改变。
watch:监视一个(或多个) key的版本变化 ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
在执行exec的时候,redis会去检查你watch的key。如果版本发生变化,就不执行。
如果watch了一个有过期时间的,且在exec之前刚好过期了,那么事务依然会执行。
当执行exec后,就会unwatch这些key;当客户端断开,也会unwatch这些key。

示例1:	watch name age score	multi	set name rao	set age 12	set score 100	exec

注意,事务和乐观锁是一起存在的,当你想要用乐观锁的时候,也要使用事务。

四、存在的问题

redis事务没有回滚机制是个硬伤,

转载地址:http://dgxui.baihongyu.com/

你可能感兴趣的文章
Canvas入门(一)
查看>>
openstack虚拟机创建流程
查看>>
openstack网络总结
查看>>
excel 查找一个表的数据在另一个表中是否存在
查看>>
centos 7 上配置dnsmasq 同时支持ipv4和ipv6的DHCP服务
查看>>
AsyncTask、View.post(Runnable)、ViewTreeObserver三种方式总结frame animation自动启动
查看>>
Android中AsyncTask的简单用法
查看>>
windows Server 2003 IIS 网站发布说明书
查看>>
S3C6410启动模式介绍
查看>>
使用JLink间接烧写S3C2410、S3C2440开发板Nor、Nand Flash的方法(暂未验证)
查看>>
Jlink + ADS调试 S3C2440
查看>>
2440初始化存储器原理(接上一篇)
查看>>
S3C2440 USB 设备控制器(转)
查看>>
Linux usb 设备驱动 (1)
查看>>
Linux usb设备驱动(2)---> usbmouse.c 源码分析
查看>>
USB芯片
查看>>
ajax工作原理
查看>>
理解Sharding jdbc原理,看这一篇就够了
查看>>
XiaoMi面试题记录
查看>>
解决跨网场景下,CAS重定向无法登录的问题(无需修改现有代码)
查看>>