Redis学习(九)事务及乐观锁

Redis事务中,一次执行多个命令,本质是一组命令的集合。一个事务中所有的命令将被序列化,即按顺序执行而不会被其他命令插入,事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
特别注意的是,Redis事务中,没有隔离级别的概念,所有的命令在事务中,并没有直接被执行,只有发起执行命令的时候才会执行。Redis事务不保证原子性,单条命令保证原子性。redis中的一个事务中如果存在命令执行失败,那么其他命令依然会被执行,没有回滚机制。
关于为什么不支持回滚,官网是这么解释的:

  • Redis 命令只会因为错误的语法而失败(并且这些问题不能在入队时发现),或是命令用在了错误类型的键上面:这也就是说,从实用性的角度来说,失败的命令是由编程错误造成的,而这些错误应该在开发的过程中被发现,而不应该出现在生产环境中。
  • 因为不需要对回滚进行支持,所以 Redis 的内部可以保持简单且快速。

实例操作

一次正常的执行事务

  • multi 标记一个事务块的开始
  • exec 执行所有事务块内的命令
    Redis学习(九)事务及乐观锁_第1张图片

放弃事务
Redis学习(九)事务及乐观锁_第2张图片
通过放弃事务,更能清楚的理解,事务中的命令只是进入一个等待执行的队列,只有在执行事务后,命令才被执行。

事务异常

  • 编译期异常 因为命令语法错误引起的异常,事务中所有的命令都不执行
    Redis学习(九)事务及乐观锁_第3张图片
  • 运行时异常 命令语法没问题,但是执行失败,单条命令执行失败,不硬性事务中其他命令的执行
    Redis学习(九)事务及乐观锁_第4张图片

Redis实现乐观锁

  • 悲观锁 总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。
  • 乐观锁 总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。

WATCH 命令可以为 Redis 事务提供 check-and-set (CAS)行为。被 WATCH 的键会被监视,并会发觉这些键是否被改动过了。 如果有至少一个被监视的键在 EXEC 执行之前被修改了, 那么整个事务都会被取消, EXEC 返回nil-reply来表示事务已经失败。WATCH 命令可以被调用多次。 对键的监视从 WATCH 执行之后开始生效, 直到调用 EXEC 为止。

正常执行成功
Redis学习(九)事务及乐观锁_第5张图片

当数据被修改后,事务执行失败
Redis学习(九)事务及乐观锁_第6张图片
Redis学习(九)事务及乐观锁_第7张图片
如果修改失败,重新获取最新的值,继续修改。
Redis学习(九)事务及乐观锁_第8张图片

你可能感兴趣的:(Redis)