Redis教程:事务和锁的使用


事务

在Redis中的事务和数据库中的事务概念类似,就是为了实现一个单独的隔离操作。在操作过程中不会被打断。

Redis中和事务相关的命令包括:

  • Multi:声明事务的开始
  • Exec: 开始执行一系列的命令
  • Discard:放弃事务的执行

比如:

bash
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set name 'lcoding'
QUEUED
127.0.0.1:6379(TX)> set age 20
QUEUED
127.0.0.1:6379(TX)> exec
1) OK
2) OK

注意,如果在运行exec之前出现错误,则在运行exec的时候,所有操作都会被取消。例如:

bash
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set name paul
QUEUED
127.0.0.1:6379(TX)> set age
(error) ERR wrong number of arguments for 'set' command
127.0.0.1:6379(TX)> exec
(error) EXECABORT Transaction discarded because of previous errors.

但如果是在运行期出现的错误,则只影响出错的语句,其余的不受影响,也就是说,Redis不支持事务的原子性。例如:

bash
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set name paul
QUEUED
127.0.0.1:6379(TX)> incr name
QUEUED
127.0.0.1:6379(TX)> exec
1) OK
2) (error) ERR value is not an integer or out of range

悲观锁(Pessimistic Lock)

悲观锁的核心点就是悲观的认为,每当操作数据的时候,都认为别人会访问数据,因此在访问数据的时候先加上锁,让别人无法访问数据,操作完毕后才解锁。

乐观锁(Optimistic Lock)

乐观锁的核心就是乐观的认为,操作数据的时候,别人不会访问数据,只有在修改数据的时候会检查一下数据是否已经被修改(check and set),进而决定是继续操作还是取消操作。其实现机制有不同的选择,比如,在获取数据后为其添加一个版本号,一旦修改数据后,就要更新数据的版本号,这样每次在更新数据的时候,拿自己获得数据的版本号和Redis中的最新版本号比较,如果一致才能继续。

在高并发的环境中,由于其效率远远高于悲观锁,因此乐观锁的使用非常频繁。比如在一个电商网站,有些商品库存只有一件,但很多用户都会发现能够把商品加入购物筐,最终下单的时候却只有一个人能够成功。

Redis中就是采用这种方式实现事务的。

Redis中实现/取消乐观锁的关键字是watch/unwatch


文章作者: 逻思
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 逻思 !