0%

redis | 事务与锁

讲一下事务和锁。

事务

一组命令的集合,一块执行。

所有的事务中的命令都会被序列化,在事务的执行过程中,会被顺序执行,并且,一次性,顺序性的执行全部命令。

  • 原子性
    • redis 单条命令是保存原子性的,但是,事务不保证原子性
  • 没有隔离级别的概念
    • redis 的一组命令,进入队列后,并不是马上执行,而是,主动执行的时候才执行
      • 队列 set set set 执行

事务过程

  • 开启事务(multi)
  • 命令入队
  • 执行事务(exec)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k 1
QUEUED
127.0.0.1:6379> set k1 2
QUEUED
127.0.0.1:6379> set k3 3
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
3) OK

放弃事务

1
2
3
4
5
6
7
8
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 1
QUEUED
127.0.0.1:6379> set k2 2
QUEUED
127.0.0.1:6379> discard
OK

编译错误

1
2
3
4
5
6
7
8
9
10
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> getset k3 # 没有这个命令,编译的时候出错
(error) ERR wrong number of arguments for 'getset' command
127.0.0.1:6379> exec # 执行的时候直接报错
(error) EXECABORT Transaction discarded because of previous errors.

运行时错误

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 "v1"
QUEUED
127.0.0.1:6379> incr k1 # 给字符串 -1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> get k2
QUEUED
127.0.0.1:6379> exec
1) OK
2) (error) ERR value is not an integer or out of range # 运行时报错,但是,下面的依然可以运行
3) OK
4) "v2"

悲观锁

  • 认为什么时候都会出现问题,无论做什么都会加锁,效率会非常低

乐观锁

  • 认为什么时候都不会出问题,所以不会上锁,更新数据的时候,判断一下,在此期间是否有人修改过这个数据
  • 获取 version
  • 更新时比较 version

redis 监控 watch

  • 正常情况
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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> decrby money 20
QUEUED
127.0.0.1:6379> incrby out 20
QUEUED
127.0.0.1:6379> exec
1) (integer) 80
2) (integer) 20
  • 冲突情况
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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> decrby money 20
QUEUED
127.0.0.1:6379> incrby out 20
QUEUED
127.0.0.1:6379> exec # 在执行这个命令之前,开启一个新的 redis-cli 客户端,然后执行 set money 1000,再次执行 exec 就会出错
(nil)
  • unwatch 解锁
请我喝杯咖啡吧~