一。总体概述
可以一次执行多个命令,即一组命令的集合。按顺序执行这个命令集,且不会被其他命令所插入执行。总的来说,事务的执行一共有三个阶段:
- 开启
- 入队
- 执行
Redis事务的常用命令
1.Multi:事务开启
从上可以发现,事务开启之后,我们再敲命令都会入队。这就跟mysql类似,先设计好一组命令出来,然后统一执行。
2.EXec:执行事务(只要是符合redis规范的命令都会被执行)
3.DISCARD :手动放弃事务
4.全体连坐:意味着这一串命令是要有一个有错, 直接全体失败。
5.“冤有头债有主”:这要与上面的结合起来看,当我们的命令没有报错但是逻辑出错了,其他正确的命令会执行但是有错的不会执行。例如:k1 是个字符串不能自增。
第四点的全体连坐是由于命令本身就有错,所以会全体失败。
6.Watch监控(很重要)
在讨论Watch之前我们先来说几个概念:
(1)前置知识
1.)表锁与行锁:在数据库技术中应用非常广泛,表锁顾名思义是锁住整张表,使用这张表的这一瞬间只能一个人在使用,并发性差但数据一致性高。行锁就是锁住一行记录,并发性好,一致性差。
2. )乐观锁、悲观锁:乐观锁与悲观锁从字面意思上很容易理解是相对的,就像并发性与数据一致性很难同时获得一样。悲观锁就类似与表锁,它保证了数据一致性但牺牲了效率。而乐观锁虽与行锁有相似之处,但是它在行锁的基础之上做了提升。
用一张图来说明乐观锁:
假如我们现在有这样一张表。它与平时的表的不同之处就在于一个version字段。假如现在有两个人张三,李四都要操作这张表并且他们几乎是同时操作(时间相差0.0几秒)他们在操作的时候version 都是1,但是这时李四先提交了,version随即变成2。那么,张三再提交时系统就会发现版本号不一致了,就会报错。张三在想提交的话需要在version 为2的基础上(类似于git先把代码同步再提交)进行更改再提交。如果张三在更改的时候version为3了,那么仍然需要重新操作再提交。这就是乐观锁的应用,不但解决了行锁数据一致性不高的问题,又拥有行锁的并发性高的优点。
所以乐观锁在多查的系统中应用非常广泛。
(2)Watch:监控某一个或多个key,在执行事务之前如果被其他命令所打断那么事务终止。乐观锁与悲观锁我们了解了之后进入正题。我们拿一个例子来说明问题,简单又直接。
假如现在你有一张信用卡 有余额 balance 和 欠账 debt。相信大家都用过信用卡,这个月余额花了多少,下个月就得还给银行多少。我们现在设置一张余额为100的欠账为0的信用卡。假如我此时吃了一碗面条花了20元。我们使用watch监控余额balance
现在余额变成了80 ,欠账为20.现在只是我们一个人在操作这个信用卡。假设我们又要吃一碗面 开启了watch监控余额,但是在吃这碗面之前有个人帮我们充了很多钱,余额发生了变化。
那么我们在提交事务的时候就会发现exec返回了空值!事务提交失败。
这是不是与我们之前说的乐观锁非常类似呢?
注意:只要执行了EXEC,之前加的监控锁都会被取消!Redis的事务不保证原子性,一条命令执行失败了,其他的仍然会执行,且不会回滚