Redis事务

一、Multi、exec、discard

  从输入Multi命令开始,输入的命令都会依次进入命令队列中,但不会执行,直到输入Exec命令后,Redis会将之前命令队列中的命令依次执行。

  在命令组队的过程中,可以使用discard命令放弃组队。

  

  但是需要注意的是:如果队列中某一条命令的语法格式不正确,那么整个队列都会解散,按时如果一个队列中,语法格式没有错误,但是执行时发现错误,那么队列中正确的命令将执行,错误的命令不执行:

  

  

  在具体介绍Redis事务之前,先复习一下悲观锁和乐观锁:

  悲观锁顾名思义,就是很悲观,每次去拿数据的时候都认为数据会被请求方修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block,直到锁打开后才可能拿到数据。传统的关系型数据库里面用到了很多悲观锁的机制,比如行锁、表锁、读锁、写锁等等,都是在做操作之前先上锁。

  而乐观锁认为,请求方拿到数据后不一定会对数据做修改,比如你打开订票软件看了看车票还充足,于是想了想过会儿再买就退出去了,这并没有对数据造成影响,所以用乐观锁维护数据,不会给数据上锁,大家都可以同时请求到数据,但是如果有一方对数据造成了修改,数据库中数据的版本号就会提升,另外一方如果手慢,在修改数据时,因为手里的数据和被前面的人修改后的数据库中的数据版本号不一致,修改就会失败,需要重新获取数据。乐观锁适用于多读的应用类型,这样可以提高吞吐量。Redis就是利用这种check-and-set的机制实现事务的。

  在Redis中使用WATCH实现乐观锁事务。

   

  上面这段命令可以看出,访问数据的双方在访问数据的同时给数据加锁,即两边同时watch balance,但这并不影响另一方对该数据的访问。两边通过watch对balance加了乐观锁以后,左边的一方先对数据进行了操作(即执行exec),redis对balance的版本号进行了提升,随后右边的一方想要执行exec修改数据时,redis发现他操作的数据版本号不是最新的,就不允许他对数据进行修改。

  unwatch命令:取消对所有key的监控,注意如果在watch命令后,执行了EXEC或者discard命令,那么被监视的key就不需要被unwatch了。

二、redis事务的三特性

  单独的隔离操作:事务中所有的命令都会序列化、按顺序的执行。事务在执行的过程中,不会被其他客户端发送来的命令请求打断。

  没有隔离级别的概念:队列中的命令在没有提交之前都不会被执行,因为事务提交前任何指令都不会被实际执行,也就不存在“事务的查询要看到十五里的更新,在是屋外查询不能看到的问题”

  不保证原子性:上面说过,如果语法没有问题,执行时一条语句执行失败,不会影响到其他命令的执行。

  

原文地址:https://www.cnblogs.com/superlsj/p/11619963.html