前言:在学习redis时候发现它的事务并不支持事务的原子性,但支持一致性,这不由得想到事务的原子性和一致性到底有什么区别呢?
事务原子性和一致性本质上他们的关注点是不一样的,但却又类似的逻辑没所以有时候容易搞混
原子性:一个事务有多个服务,如果当前事务的一个服务失败了,那边在失败服务之前执行成功的服务就会回滚,(通俗的说就是,在一个事务中要么都失败,要么都成功)
一致性:它的关注点在数据上,比如A给B转账10元,那么A账户必须扣10元,B账户必须增加10元,这就是事务的一致性
一,事务
redis事务本质:一组命令的集合!一个事务中的所有命令都会被序列化,在事务执行过程中,会按照顺序执行
特点:一次性,顺序性,排他性!执行一些列的命令
注意:1.redis是不支持事务的原子性的:(但是支持一致性)
redis单条指令是支持原子性的,但当多条redis指令合并成一个事务后不支持事务的原子性
不支持原子性带来的特点:
当一个事务中有多个redis指令时,如果某个指定报错,当前事务并不会停止,而是抛出异常然后继续执行下面的指令
2.redis事务没有隔离级别概念的
异常就不会产生幻读,脏读,不可重复读的概念的
redis的事务生命周期:
开启事务(MULTI开启一个事务)
--->命令入队(在开启事务的时候,每次操作的命令将会被插入到一个队列中,同时这个命令并不会被真的执行)
-->执行事务(EXEC命令进行提交事务.执行事务)
discard #取消事务(事务队列中的事务都不会被执行)
二,乐观锁,redis的watch监控实现乐观锁
拓展:悲观锁
对任何操作都持消极的态度,所以无论做什么事情都加锁
乐观锁:
很乐观,认为什么操作都是顺利的,所以仅会在更新数据的时候去判断一下,在执行乐观锁的事务期间是否有人修改过这个数据
锁测试:
redis锁:watch(乐观锁)
格式:watch {key name}
1.模拟单线程正常的一个事务的执行(成功)
2.模拟并发操作,在事务A在存取钱过程中,另一个线程(事务B)同时在向money中存钱
此时会出现一个问题,事务A(有乐观锁)在执行(exec)时就会报错,
注意:这里有两个关注点,事务A用的时watch去充当乐观锁(只有在事务提交(执行)时才会检查数据是否被改动,所以在exec时才报错)
有乐观锁事务执行失败的解决方法:
unwatch(解锁)————>watch {key name} #重新上锁,相当于将数据更新了一遍,所以事务就能成功了
注意:无论事务是否执行成功,Redis都会取消watch的监控
如果修改失败了,获取最新的值就好