Redis:事务,乐观锁(redis的watch监控实现乐观锁)

前言:在学习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的监控

   如果修改失败了,获取最新的值就好

 

posted @ 2021-03-25 20:57  凸然猿  阅读(256)  评论(0编辑  收藏  举报