事务
在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