Redis事务学习,首先了解几个命令
multi # 开启事务
discard # 取消事务
watch # 乐观锁
unwatch # 解锁
开启事务
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 v3
QUEUED
127.0.0.1:6379(TX)> del k1
QUEUED
127.0.0.1:6379(TX)> set k3 v3
QUEUED
127.0.0.1:6379(TX)> get k3
QUEUED
127.0.0.1:6379(TX)> exec # 执行事务
1) OK
2) OK
3) (integer) 1
4) OK
5) "v3"
放弃事务
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)> discard # 放弃事务
OK
如果在事务开启的过程中,我们的命令写错了,也就是语法出现了错误,那么整个事务都不会被执行成功
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)> gett k2
(error) ERR unknown command `gett`, with args beginning with: `k2`,
127.0.0.1:6379(TX)> get k1
QUEUED
127.0.0.1:6379(TX)> exec
(error) EXECABORT Transaction discarded because of previous errors.
如果我们语法没有写错,只是出现了类似于程序中1/0的情况,那么只有那一条命令不会被执行成功,其它的还是可以成功的。
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set k1 zhangsan
QUEUED
127.0.0.1:6379(TX)> incr k1 # 让一个字符串增加1
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 # 报出的错误是,它不是一个Integer类型的
3) OK
127.0.0.1:6379> get k1
"zhangsan"
127.0.0.1:6379> get k2
"v2"
乐观锁
单线程的演示
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 # 开启锁,监控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> unwatch # 事务执行失败要先解锁
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) 980
2) (integer) 40