redis中事务机制及乐观锁的实现

Redis事务机制

在MySQL等其他数据库中,事务表示的是一组动作,这组动作要么全部执行,要么全部不执行。 

 Redis目前对事物的支持相对简单。Redis只能保证一个client发起的事务中的命令可以连续的执行,而中间不会插入其他的client命令。当一个client在一个链接中发出multi命令时,这个链接会进入一个事务上下文,该连接后续的命令不会立即执行,而是先放到一个队列中,当执行exec命令时,redis会顺序的执行队列中的所有命令。

Multi 开启事务:
127.0.0.1:6379[1]> multi #开启事务
OK
127.0.0.1:6379[1]> set age 15 #数据操作命令
QUEUED
127.0.0.1:6379[1]> set age 20 #数据操作命令
QUEUED
127.0.0.1:6379[1]> exec #执行事务
1) OK
2) OK
127.0.0.1:6379[1]> get age
"20"
Discard:取消事务,该命令实际是清空事务队列中的命令并退出事务上下文,也就是事务回滚。
127.0.0.1:6379[1]> get age
"20"
127.0.0.1:6379[1]> multi
OK
127.0.0.1:6379[1]> set age 25
QUEUED
127.0.0.1:6379[1]> set age 30
QUEUED
127.0.0.1:6379[1]> discard #清空事务队列
OK
127.0.0.1:6379[1]> get age
"20"

注意redis事务问题:通常事务队列中如果有一个事务失败则整个事务都会回滚,但在redis中其他事务命令不会回滚。

 乐观锁:redis大多数是基于数据版本(version)的记录机制实现的。即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表添加一个version字段来实现。在读取数据时,将此版本号一同读出,之后更新时对此版本号加1。此时,将提交数据的版本号与数据库表对应记录的当前版本号进行对比,如果提交的数据版本号大于数据库当前版本号,则予以更新,否则认为是过期数据。

watch监控:watch命令会监控给定的key,当exec时如果监视的key从调用watch后发生过变化,则整个事务会失败。也可以调用watch多次监视多个key,这样就对指定事务key加乐观锁了。注意watch的key是对整个链接有效的,事务也一样。如果链接断开,监视和事务都会被自动清除。当然exex、discard、unwatch命令都会自动清除链接中的所有监视。

在redis中对乐观锁的实现:

假设有一个age的key,我们开启两个session来对age进行赋值操作。

session1:

127.0.0.1:6379> get age
"10"
127.0.0.1:6379> watch age #打开对age键的监控(监控其他操作是否对age键有修改操作)
OK
127.0.0.1:6379> multi #开启事务上下文
OK

session2:

127.0.0.1:6379> set age 20
OK
127.0.0.1:6379> get age
"20"

在session2中直接操作age

再看session1:

127.0.0.1:6379> set age 30 #在session2中操作age后,我们在session1中继续操作age
QUEUED
127.0.0.1:6379> exec #执行事务 返回nil 事务执行不成功。
(nil)
127.0.0.1:6379> get age
"20"

在这里我们发现事务不能执行成功,这就是因为session1中的数据版本已经小于数据库中的数据版本。这就是redis中的乐观锁。

行百里者半九十。

总结

以上就是本文关于redis中事务机制及乐观锁的实现的全部内容,希望对大家有所帮助,感兴趣的朋友可以继续参阅本站:sqlserver:查询锁住sql以及解锁方法、几个比较重要的MySQL变量、MySQL主库binlog(master-log)与从库relay-log关系代码详解等,如有不足之处,欢迎留言指出,小编会及时回复大家并进行改正,感谢朋友们对本站的支持!

(0)

相关推荐

  • Redis教程(八):事务详解

    一.概述: 和众多其它数据库一样,Redis作为NoSQL数据库也同样提供了事务机制.在Redis中,MULTI/EXEC/DISCARD/WATCH这四个命令是我们实现事务的基石.相信对有关系型数据库开发经验的开发者而言这一概念并不陌生,即便如此,我们还是会简要的列出Redis中事务的实现特征: 1). 在事务中的所有命令都将会被串行化的顺序执行,事务执行期间,Redis不会再为其它客户端的请求提供任何服务,从而保证了事物中的所有命令被原子的执行. 2). 和关系型数据库中的事务相比,在Red

  • Redis 事务与过期时间详细介绍

    Redis 事务与过期时间详细介绍 一.Redis事务: Redis中支持事务,事务即为当我们需要执行几条命令时,要么这几条命令都不执行,要么都执行: 1.开始事务写入: multi 2.然后写入命令,注意写完事务要执行的每条命令之后回车即可,命令会自动入队: lpush art:1 hello lpush art:1 nihao 3.执行事务: exec Redis则会保证事务中的所有命令要么都执行,要么都不执行. 二.Redis过期时间: 实际开发中经常会遇到一些有时效性的数据,比如缓存,过

  • 【Redis缓存机制】详解Java连接Redis_Jedis_事务

    Jedis事务 我们使用JDBC连接Mysql的时候,每次执行sql语句之前,都需要开启事务:在MyBatis中,也需要使用openSession()来获取session事务对象,来进行sql执行.查询等操作.当我们对数据库的操作结束的时候,是事务对象负责关闭数据库连接. 事务对象用于管理.执行各种数据库操作的动作.它能够开启和关闭数据库连接,执行sql语句,回滚错误的操作. 我们的Redis也有事务管理对象,其位于redis.clients.jedis.Transaction下. Jedis事

  • redis中事务机制及乐观锁的实现

    Redis事务机制 在MySQL等其他数据库中,事务表示的是一组动作,这组动作要么全部执行,要么全部不执行. Redis目前对事物的支持相对简单.Redis只能保证一个client发起的事务中的命令可以连续的执行,而中间不会插入其他的client命令.当一个client在一个链接中发出multi命令时,这个链接会进入一个事务上下文,该连接后续的命令不会立即执行,而是先放到一个队列中,当执行exec命令时,redis会顺序的执行队列中的所有命令. Multi 开启事务: 127.0.0.1:637

  • MyBatis-Plus通过version机制实现乐观锁的思路

    MyBatis-Plus是通过version机制实现乐观锁的. 大致思路: 取出记录,携带记录的当前version: 更新记录的时候,比较记录当前的version是否有改变: 如果version未改变,则更新记录,并更新version,一般值+1: 如果version改变了,则不更新记录. version机制的核心思想就是,假设发生并发冲突的几率很低,只有当更新数据的时候采取检查是否有冲突,而判断是否有冲突的依据就是version的值是否被改变了. 配置 MyBatis-Plus中配置乐观锁分两

  • redis中RedissonLock如何实现等待锁的

    目录 前言 问题 方案 tryLock unlockInnerAsync 思考 前言 经常会有到这样的需求,就是在一个查询接口,第一次查询的时候,如果没有查询到就要执行初始化方法,初始化数据出来,之后的查询就可以直接查询库里的数据了.这样设计的目的是,如果需要初始化的数据特别大,无法再一次调用方法里处理完,或者说数据并不是每条都需要初始化,这种情况下,优先查询的数据优先初始化. 问题 这种方案随之而来就会引发一个问题.查询接口众所周知是个自然幂等的,不需要我们额外去做幂等处理.但是在方案中,这个

  • 深入分析MSSQL数据库中事务隔离级别和锁机制

    锁机制 NOLOCK和READPAST的区别. 1.       开启一个事务执行插入数据的操作. BEGIN TRAN t INSERT INTO Customer SELECT 'a','a' 2.       执行一条查询语句. SELECT * FROM Customer WITH (NOLOCK) 结果中显示"a"和"a".当1中事务回滚后,那么a将成为脏数据.(注:1中的事务未提交) .NOLOCK表明没有对数据表添加共享锁以阻止其它事务对数据表数据的修

  • 详解redis中的锁以及使用场景

    分布式锁 什么是分布式锁? 分布式锁是控制分布式系统之间同步访问共享资源的一种方式. 为什么要使用分布式锁? ​ 为了保证共享资源的数据一致性. 什么场景下使用分布式锁? ​ 数据重要且要保证一致性 如何实现分布式锁? 主要介绍使用redis来实现分布式锁 redis事务 redis事务介绍: ​ 1.redis事务可以一次执行多个命令,本质是一组命令的集合. ​ 2.一个事务中的所有命令都会序列化,按顺序串行化的执行而不会被其他命令插入 ​ **作用:**一个队列中,一次性.顺序性.排他性的执

  • Redis中一些最常见的面试问题总结

    前言 经过长达一周的奔波和面试,电话面试,回首今天终于成功的入职了,总共面试了大概10家公司,包括阿里,京东,IBM等等,京东技术过了,学历因为非统招就被pass了,阿里面了2次电话面试就没下文了,估计是我当时最后提问题的时候减分了吧,其他的也有一些offer,不是不想去,就是了无音讯了,眼看年关将近,也由不得我挑挑拣拣了,就直接进了我现在这家公司,主要是感觉公司人不错,薪水这方面也就没有计较太多.好了,书归正文,今天小编就大家送上我精心准备的关于Redis方面的面试题,希望可以帮到还在求职路上

  • 深入理解Yii2.0乐观锁与悲观锁的原理与使用

    本文介绍了深入理解Yii2.0乐观锁与悲观锁的原理与使用,分享给大家,具体如下: Web应用往往面临多用户环境,这种情况下的并发写入控制, 几乎成为每个开发人员都必须掌握的一项技能. 在并发环境下,有可能会出现脏读(Dirty Read).不可重复读(Unrepeatable Read). 幻读(Phantom Read).更新丢失(Lost update)等情况.具体的表现可以自行搜索. 为了应对这些问题,主流数据库都提供了锁机制,并引入了事务隔离级别的概念. 这里我们都不作解释了,拿这些关键

  • Java并发问题之乐观锁与悲观锁

    首先介绍一些乐观锁与悲观锁: 悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁.传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁.再比如Java里面的同步原语synchronized关键字的实现也是悲观锁. 乐观锁:顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版

  • Redis 缓存淘汰策略和事务实现乐观锁详情

    目录 缓存淘汰策略 标题LRU原理 标题Redis缓存淘汰策略 设置最大缓存 淘汰策略 Redis事务 Redis事务介绍 MULTI EXEC DISCARD WATCH Redis 不支持事务回滚(为什么呢) Redis乐观锁 Redis乐观锁实现秒杀 缓存淘汰策略 标题LRU原理 LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”. 最常见的实现是使用一个链表保存缓存数据,

  • Redis如何使用乐观锁(CAS)保证数据一致性

    目录 场景 问题模拟 CAS 来保证数据一致性 场景 在 Redis 中经常会存在这么一种情况,读取某一个 key 的值,做一些业务逻辑处理,然后根据读取到的值来计算出一个新的值,重新 set 进去. 如果客户端 A 刚读取到 key 值,紧接着客户端 B 就修改这个 key 的值,那么就会存在并发安全的问题. 问题模拟 假设 Redis Server 有个键名为 test 的key,里面存放的是一个 json 数组 [1, 2, 3]. 下面让我们模拟一下,客户端 A 与 客户端 B 同时访问

随机推荐