redis基本事务操作+实现乐观锁(watch)

  • Post author:
  • Post category:其他


一、什么是原子性??

同时失败或者同时成功!!

理解如下:

原子性即是,A原有5块石头,B原有3块石头;现有如下操作:

A让C给予B一块石头,那么应该发生的事情有,A失去一块石头,变为4块,B得到一块石头变为5块;此时交易成功。

不排除有意外情况,比如C在给予B的过程中,B出门了,那么,我们称这个操作失败了,要进行回滚。回滚就是回到事务开始之前的状态,

A还是5块石头,B还是4块石头。

我们把这种要么一起成功(A帐户成功减少一块石头,同时B得到一块石头),要么一起失败(A回到原来状态,B也回到原来状态)的操作叫原子性操作。

如果把一个事务可看作是一个程序,它要么完整的被执行,要么完全不执行。这种特性就叫原子性。


redis事务的本质:一组命令的集合!! 一个事务的命令会被序列化,在执行事务的时候会按顺序执行,一次性、排他性、顺序性。

redis单条命令是保存原子性的,但事物不保证原子性

redis事务没有隔离级别的概念




一、redis的事物:

  1. 开启事务
  2. 命令入队
  3. 执行事务
 127.0.0.1:6379> MULTI  开启事务
OK
127.0.0.1:6379> set a 1  命令入队
QUEUED
127.0.0.1:6379> set b 2
QUEUED
127.0.0.1:6379> set c 3
QUEUED
127.0.0.1:6379> set d 4
QUEUED
127.0.0.1:6379> get a 
QUEUED
127.0.0.1:6379> get c
QUEUED
127.0.0.1:6379> EXEC  执行事务
1) OK
2) OK
3) OK
4) OK
5) "1"
6) "3"
 127.0.0.1:6379> DISCARD   取消事务(事务队列中的命令都不会被执行)
注意当执行完exec之后一个事务已经被执行完。若再次执行事务需要重新开始创建事务



二、监控



监控!!

悲观锁:无论什么时候都会枷锁,认为什么时候都会出现问题!

乐观锁:无论什么时候都不会枷锁,认为什么时候都不会出现问题!更新数据判断一下再次期间是否有人更改过此数据。

获取version,更新的时候比较version

redis检测测试:

127.0.0.1:6379> set qian 100    设置一共100元
OK
127.0.0.1:6379> set out 0   设置话费0元
OK
127.0.0.1:6379> WATCH qian  监控此key相当于获取值
OK
127.0.0.1:6379> MULTI  开始事务
OK
127.0.0.1:6379> DECRBY qian 20    件20 
QUEUED
127.0.0.1:6379> INCRBY out 20   加20
QUEUED
127.0.0.1:6379> EXEC  事务执行完毕
1) (integer) 80
2) (integer) 20

测试多线程修改值,监视失败!!

打开两个终端shell
在第一个shell中
127.0.0.1:6379> WATCH qian    监控相当于获取值
OK
127.0.0.1:6379> MULTI  开始事务
OK
127.0.0.1:6379> DECRBY qian 50  减50
QUEUED
127.0.0.1:6379> INCRBY out 50  加50
QUEUED
先不要执行事务,直接在第二个shell终端中连接redis(也就是重新打开一个线程)
127.0.0.1:6379> set qian 2000  重新更改值为2000
OK
然后再去第一个shell中执行事务。会发现事务执行失败
为什么会失败??
因为监控的时候获取值。之后执行事务的时候会去比较值当发现值不一致时会失败
127.0.0.1:6379> EXEC
(nil)

乐观锁失效如何恢复??

127.0.0.1:6379> UNWATCH  首先解锁后面依次执行
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> DECRBY qian 20 
QUEUED
127.0.0.1:6379> INCRBY out 20
QUEUED
127.0.0.1:6379> EXEC
1) (integer) 1980
2) (integer) 40



版权声明:本文为qq_46089299原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。