Redis事务本质
一组命令的集合!一个事务中的所有命令都会被序列化,在事务执行过程中,会按照顺序执行
Redis事务特点
- 一次性
- 顺序性
- 排他性
==Redis单条命令是保证原子性的,但是事务不保证原子性。==
==Redis事务没有隔离级别的概念==
事务执行命令
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set k1 v1
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> get k2
QUEUED
127.0.0.1:6379(TX)> exec
1) OK
2) OK
3) "v2"
127.0.0.1:6379> get k2
"v2"放弃事务命令
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set k5 v5
QUEUED
127.0.0.1:6379(TX)> set k6 v6
QUEUED
127.0.0.1:6379(TX)> DISCARD
OK
127.0.0.1:6379> get k5
(nil)编译型异常,所有的命令都不会执行
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set k1 v1
QUEUED
# 命令使用错误
127.0.0.1:6379(TX)> set k2
(error) ERR wrong number of arguments for 'set' command
127.0.0.1:6379(TX)> set k3 v3
QUEUED
127.0.0.1:6379(TX)> exec
(error) EXECABORT Transaction discarded because of previous errors.
# 所有命令都未执行
127.0.0.1:6379> keys *
(empty array)运行时异常,错误的命令抛出异常,其他命令继续执行(没有原子性的表现)
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set k1 v1
QUEUED
127.0.0.1:6379(TX)> incr k1
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
#运行时抛出错误异常,其他命令继续执行
127.0.0.1:6379(TX)> exec
1) OK
2) (error) ERR value is not an integer or out of range
3) OK
127.0.0.1:6379> get k1
"v1"
127.0.0.1:6379> get k2
"v2"乐观锁实现
悲观锁:
认为什么时候都会出问题,无论干什么都会加锁
乐观锁:
认为什么时候都不会出问题,所以不会上锁。更新数据的时候去判断一下,在此期间是否有人更改了数据。
- 获取version
- 更新的时候比较version
正常加锁执行
127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> set out 0
OK
127.0.0.1:6379> watch money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> decrby money 20
QUEUED
127.0.0.1:6379(TX)> INCRBY out 20
QUEUED
127.0.0.1:6379(TX)> exec
1) (integer) 80
2) (integer) 20加锁后,数据被篡改
127.0.0.1:6379> watch money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> decrby money 10
QUEUED
127.0.0.1:6379(TX)> incrby money 10
QUEUED
#另一线程此时修改了数据
127.0.0.1:6379(TX)> exec
(nil)# 另一线程
127.0.0.1:6379> set money 1000
OK
127.0.0.1:6379> get money
"1000"