redis似乎并没有“事务”,那些用到“事务”的人在做什么?

请考虑如下情景(在RDB持久化模式下): 1.后台有个进程执行bgsave,处理完毕A键, 2.这时候有个事务在执行,修改了内存里面的A键和B键 3.…
关注者
125
被浏览
50,643

26 个回答

昨天刚看到这个问题:redis似乎并没有“事务”,那些用到“事务”的人在做什么?

我想提问这个问题的大概还不知道什么是事物吧!

你要知道什么是事物!

Redis事务是一个单独的隔离操作!

事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。 Redis事务的主要作用就是串联多个命令防止别的命令插队。

事务从开始到执行会经历以下三个阶段:

  1. 第一个阶段:开始事务
  2. 第二个阶段:命令入队
  3. 第三个阶段、执行事务。

比如:秒杀场景!

在大型秒杀高并发的流量下,利用redis事物技术可以防止最后一件商品不会被多人同时购买。

解决方案

  • 使用setnx 设置一个公共锁。
setnx lock-key value

存在的问题:假设线程获取了锁之后,在执行任务的过程中挂掉,来不及显示地执行del命令释放锁,那么竞争该锁的线程都会执行不了,产生死锁的情况。

解决方案:设置锁超时时间

第二:使用set命令加锁并设置锁过期时间:

命令格式:set <lock.key> <lock.value> nx ex <expireTime>

第三:基于setnx、get、getset的分布式锁

上面这几种基本上都存在问题,当 redis 是单点的情况下,当发生故障时,则整个业务的分布式锁都将无法使用。高可用就会出现问题

这里补充一篇redis的高并发如何保证:

第四种:基于RedLock的分布式锁

redisson在获取锁之后,会维护一个看门狗线程,当锁即将过期还没有释放时,不断的延长锁key的生存时间

举个简单的例子来说,利用setnx命令的返回值特征,有值则返回设置失败,无值则返回设置成功。

  • 对于返回设置成功的,拥有控制权,进行下一步具体业务操作。
  • 对于返回值设置失败的,不具有控制权,排队或者等待。

操作完毕之后,通过del键值对来释放锁。

接下来说一下事物的应用场景:

1、缓存

这个不用说,可以大大减轻关系型数据库的压力。

2、服务内跨/外夸数据库请求

3、消息列队

4、数据临时存储位置

使用token(令牌)作为用户登录系统时的身份标识,这个token就可以在Redis中临时存储。

5、分布式锁,分布式环境下解决Session不一致问题时的Session库

4、流式数据去重

5、可以用于生成有序的主键id

在分布式项目中经常会用到生成唯一主键,或者生成顺序号,现通过Redis实现顺序号的生成

举个例子:

在某银行的软件开发严格重视事务处理,比如常见的转账操作,一方的账户金额减少,对应的是另一方的账户金额增加,这个过程需要使用到事务机制,不然转账不能成功

总结来说

Redis事务就是一次性、顺序性、排他性的执行一个队列中的一系列命令。

当然在处理事物场景的时候,一般都是配合MySQL使用的,你可能也会遇到一些问题,一般也是缓存问题


PS:收藏等于白嫖,点赞才是真情!

最后给大家的一个建议就是:

大家学习一定要找对圈子

@终端研发部

我是程序员于小二,一个经常浪迹于知乎的北漂者,原创不易,如果你觉得我说的很中肯, 最后也别忘记点赞收藏哦。关注我,每天分享更多的职场经验和面试技巧~

Redis主要是针对单个key,或者说,单个数据对象的操作,这样,事务里的多对象Atomic要求就很低。

当Redis的命令执行多对象操作,比如MSET命令,或者Redis的Transaction命令(也含LUA),涉及多数据对象时,其内部,是顺序执行的(这也是我们说的,Redis是单线程架构),相当于传统DB的Serialize级别。这时,ACID里的Isolation在Redis里就极其简化,因为不存在两个并发事务互相的干扰,即Redis不存在并发命令。

Redis的Transaction命令,不是严格意义的事务,因为缺乏Rollback。

磁盘的AOF或RDB文件,只是个备份,不是传统意义上的DB的Dataset包含磁盘数据的概念,所以,把Redis的磁盘数据,看成整个Dataset的一部分,是不对的,还是只考虑Redis的内存特性,即它是内存数据库。