我们知道mysql中的事务实现了一组不可分割的数据库操作,这些操作被打包成一个执行单元,要么同时都成功完成,要么同时都不成功完成,那么redis中有没有事务操作呢?严格来说是没有的,redis里的事务概念仅仅是一次性大包执行多个命令,其中部分命令执行失败,其他命令依然会执行成功,并没有mysql中的事务回滚操作,但是今天在这里跟大家讲的是redis中的乐观锁机制,它可以实现接近于事务的功能,废话不多说,直接上例子为大家做一个直观的说明:

1、启动redis服务端:

[root@VM_0_8_centos ~]# redis-server
10320:C 11 Aug 2019 19:22:50.415 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
10320:C 11 Aug 2019 19:22:50.415 # Redis version=5.0.3, bits=64, commit=00000000, modified=0, pid=10320, just started
10320:C 11 Aug 2019 19:22:50.415 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
10320:M 11 Aug 2019 19:22:50.416 * Increased maximum number of open files to 10032 (it was originally set to 4864).
                _._
           _.-``__ ''-._
      _.-``    `.  `_.  ''-._           Redis 5.0.3 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 10320
  `-._    `-._  `-./  _.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |           http://redis.io
  `-._    `-._`-.__.-'_.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |
  `-._    `-._`-.__.-'_.-'    _.-'
      `-._    `-.__.-'    _.-'
          `-._        _.-'
              `-.__.-'

10320:M 11 Aug 2019 19:22:50.419 # Server initialized
10320:M 11 Aug 2019 19:22:50.420 * Ready to accept connections

2、打开另一个终端窗口,用redis-cli命令连接redis服务。暂叫它clientA:

[root@VM_0_8_centos ~]# redis-cli
127.0.0.1:6379>

3、再打开另一个终端窗口,用redis-cli命令连接redis服务。暂叫它clientB:

[root@VM_0_8_centos ~]# redis-cli
127.0.0.1:6379>

4、clientA执行如下命令:

127.0.0.1:6379> WATCH testHashKey
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> HSET testHashKey name itboy
QUEUED
127.0.0.1:6379> HSET testHashKey age 30
QUEUED
127.0.0.1:6379>

5、clientB执行如下命令:

127.0.0.1:6379> WATCH testHashKey
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> HSET testHashKey name itgirl
QUEUED
127.0.0.1:6379> HSET testHashKey age 20
QUEUED
127.0.0.1:6379>

6、这一步如果clientA先执行EXEC命令,clientB后执行EXEC命令,是否都会成功呢?

clientA先执行EXEC命令:

127.0.0.1:6379> EXEC
1) (integer) 1
2) (integer) 1
127.0.0.1:6379>

clientB后执行EXEC命令:

127.0.0.1:6379> EXEC
(nil)
127.0.0.1:6379> HGET testHashKey age
"30"
127.0.0.1:6379> hget testHashKey name
"itboy"

我们看到clientB执行EXEC命令的时候返回“(nil)”,说明执行失败了,age的值最后被设置成30,name是itboy,说明clientA执行成功了,watch结合MULTI ….EXEC这组命令间接实现了对一个key的乐观锁机制,保证了数据的一致性问题。

发表评论

电子邮件地址不会被公开。 必填项已用*标注