文章目录
Redis中的事务以及在Redis中使用乐观锁
之前学习的MySQL关系型数据库中事务的四个特征
原子性:指事务是一个不可再分的工作单位,事务中的操作要么都发生,要么都不发生,就好比A账户给B账户转钱,这个事务有两个操作,第一个是A账户减去钱,第二个是B账户增加钱,原子性就是说这两个操作要么同时都发生,要么都不发生,不可能一个发生一个不发生;
一致性:指事务发生前后,数据库中的总数据是不能发生变化的,仍举一个例子,A账户给B账户转钱,假设转钱之前A,B账户钱数的总和是2000元,那么转钱之后,A,B账户钱数的总和也要是2000元;
隔离性:指一个事务的运行不影响另一个事务的运行,比如甲,乙两个事务都操作同一个共享数据,甲事务和乙事务对共享数据的操作互相不影响,因为甲,乙事务都各自有存储自己数据的空间!
持久性:指事务被提交之后,数据库中的数据就会发生改变并持久的保存在数据库中,不会发生回滚;
Redis事务的解释说明
Redis事务的基本概念:可以一次性把很多redis单条命令放到一个集合队列中,然后在执行exec命令之前,这些被添加到队列中的命令并不会被执行,执行完exec命令之后,所有的命令,一次性,顺序性,排他性的全部执行。
Redis事务不像之前的关系型数据库,之前的Mysql中的关系型数据库是有原子性的,但是Redis事务没有原子性,执行exec命令之后,即便队列中的一条redis命令执行失败,队列中的其它redis单条命令仍会执行,而且redis事务是不会回滚的。
Redis事务也没有隔离性,因为在执行完multi命令之后,往队列中添加Redis单条命令的时候,这些单条命令并不会执行,不像之前学习Mysql的关系型数据库,事务中每条sql语句都是会执行的,所以在Redis事务中不存在事务里面可以查看到更新的共享数据,而事务外面却不可以查看更新的共享数据,因为Redis事务中的所有redis单条数据根本没有执行,事务里面和事务外面的单条数据都是相同的。
Redis的单条命令是有原子性的,但是Redis事务是没有原子性的!
Redis事务的三个阶段
开启事务(multi,此命令执行之后,之后写的所有的Redis单条命令都不会执行而是会存放到一个队列里面)
命令入队(此阶段写的所有的Redis单条命令都不会被执行而是直接被放到队列里面)
执行事务(exec,此命令执行之后,队列中的所有的Redis单条命令会一次性,顺序性,排他性的全部执行)
正常执行Redis事务的测试
测试如下图:
放弃Redis事务的测试
相关命令:discard,此命令可以放弃Redis事务中所有的Redis单条命令;
测试如下图:
Redis事务中出现的两种异常
编译性异常(代码有问题!如命令拼写错误!):Redis事务中只有有一个Redis单体命令出现编译性异常,那么这个事务中所有的Redis单体命令都不会被执行;
运行时异常(代码没有问题!但是逻辑有问题,如1/0在运行时就会报错):Redis事务中一个单体命令的运行异常不会影响其它的Redis单体命令。其它的单体命令仍会执行;
如下图:
Redis中使用乐观锁
Redis中使用乐观锁,会先在事务开始之前,也即是执行multi命令之前,使用watch命令监视特定的字段;假设watch监视的是A_money字段,在事务开始之前,A_money的值是100,然后watch监视的A_money值就是100,如果在事务执行的时候即执行exec命令的时候A_money字段的值仍是100,表示此事务执行期间没有其他事务插队执行,那么此事务这时可以正常执行;但是如果在事务执行的时候即执行exec命令的时候,发现A_money字段的值是1000,那么就表示在此事务执行之前,已经有其它的线程插队执行了,并且已经更改了数据,所以这个时候在执行exec命令此事务就不会执行了,这与之前我们在MyBatisPlus中所讲的乐观锁的version字段道理是一样的。
具体的测试情况如下图:
unwatch命令可以取消watch对所有key的监控,如下图: