相信phper都或多或少知道事务,在一些场景中也会经常用到事务。比如购买了一个产品,需要向订单表插入一条数据,还要修改用户表的余额字段等等。这两个操作必须是要么一起成功,要么都失败,否则就会产生数据不一致的情况。
Redis中也支持事务的特性。虽然没有传统关系型数据库的事务功能那样强大,但它的使用非常简单。
事务
MULTI
multi标志个一个事务的开始。随后的指令将在执行EXEC时作为一个原子执行。
DISCARD
Discard 命令用于取消事务,放弃执行事务块内的所有命令。
EXEC
exec命令用于执行所有事务块内的命令
介绍了上面三个命令后,我们来完成一个小功能,用户关注:
比如A用户关注了B,那么需要在A的关注表中添加B,此外B的粉丝表中要添加A;这两个操作要作为一个原子来执行的。
实现代码如下:
$redis->multi() ->sadd('like:A', 'B') ->sadd('fans:B', 'A') ->exec();
是不是使用起来非常简单。
乐观锁
首先来介绍下什么是乐观锁,以及它对应的悲观锁。
悲观锁:想法很悲观啦,对自己的男朋友不放心,只要自己和男朋友在一起时,任何人都接触不了他男朋友。Mysql中的行锁、表锁等,都属于悲观锁。
乐观锁:很乐观很天真,对自己的男朋友放心,自己和男朋友在一起时,有其他朋友找她男朋友聊天时,她不会阻止。但每次两人在一起时,她都会对男朋友的最近状态做评定,判断他是否有问题。没有问题才会继续和他在一起,否则就拜拜。
下面有一个场景:Redis存放着token,但是这个token是要隔一段时间就需要更新的。悲观锁的作为是,修改前我就要将它锁定,这个时候其他任何请求都不能修改他,直到我修改完成后,才会解除锁定。乐观锁的作法则是,修改的时候不会锁定,但修改前我会观察它的状态,如果他没有被修改,那么我就做修改,如果状态改变了,那么我就不做修改的操作。、
Redis中如何使用乐观锁的呢?
Redis中提供了一个命令Watch,标记所有指定的key 被监视起来,在事务中有条件的执行。
下面是伪代码:
$redis->watch('token'); $redis->multi() ->set('token','sfwefawfwefa323') ->exec();
乐观锁和悲观锁都有自己的使用场景,大家可以自行查阅相关信息,这里就不多赘述了。