1、redis的事务是什么
可以一次执行多个命令,本质是一组命令的集合,一个事务中的所有命令都会被序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞(排队时后来者插到先到者前面的行为。)
也就是说,在队列中,一次性、顺序性、排他性的执行一系列命令的行为。
看看官方的介绍:
注: redis 的事务是能够使用 MULTI 命令的行为,这个命令通常会响应为 OK,在这种情况下,使用者可以进行多个命令的操作,redis会安排它们入队列而不是执行这些命令,这些所有命令在键入 EXEC 时才会被调用。
如果调用 DISCARD 命令将会刷新事务队列,而后退出事务。
2、具体的实际操作
a、 MULTI: 标记一个事务块的开始
EXEC: 执行所有事务块内的命令
DISCARD: 取消事务,放弃执行事务块内的所有命令
注:图示为正常执行的情况
注:图示为放弃事务执行的情况
注: 图示中,键入 getset v2 时发生了错误,所以在最后执行时所有命令都没有执行。(类似于Java 的编译期错误。)
注:k1 为字符串,不可以进行数字操作,但是在执行了 EXEC 后才发现,后续的操作一样执行。(类似于 java 的运行期错误。)
b、WATCH: 监视一个(或者多个)key,如果在事务之前这个(或者这些)key被其他的命令所改动,那么事务将会被打断
UNWATCH: 取消 WATCH 命令对所有 key 的监视。
注: 先设置 balance、debt 两个变量,然后再执行watch balance 和 multi 命令,在执行multi
命令之后,使用另一个终端开启另外一个客户端并改动 balance 的值后发现,exec 指令命令并不成功。(即redis事务不允许加塞。)
注: 可以看到,unwatch 可以取消对所有 key 的监控,再 watch 一下,获取最新的 key 的状态。
3、redis事务机制的三特性:
a、单独的隔离操作:事务中的所有命令都会序列化,按照顺序进行执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
b、没有隔离级别的概念:队列中的命令没有提交之前都不会实际的被执行,因为事务提交之前任何指令都不会被实际执行,也就不存在“事务内的查询要看到事务里的更新,事务外的查询不能够看到”的问题。
c、不保证原子性: redis同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行。没有回滚操作。
附:乐观锁和悲观锁的理解
悲观锁: (Pessimistic Lock),顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会被阻塞,直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁、表锁、读锁、写锁等。都是在操作之前上锁。
乐观锁: (Optimistic Lock),顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制,乐观锁适用于多读的应用类型,这样可以提高吞吐量。(提交版本必须大于记录当前版本才能够执行更新。)