Redis 的事务功能详解

有没有人在啊,想请问下,Redis 的事务功能详解
最新回答
独我暖阳

2026-10-20 14:03:26

Redis的事务功能详解

Redis中的事务(transaction)是一组命令的集合。事务同命令一样都是 Redis 的最小执行单位,一个事务中的命令要么都执行,要么都不执行。事务的原理是先将属于一个事务的命令发送给 Redis,然后再让 Redis 依次执行这些命令。

Redis保证一个事务中的所有命令要么都执行,要么都不执行。如果在发送 EXEC 命令前客户端断线了,则 Redis 会清空事务队列,事务中的所有命令都不会执行。而一旦客户端发送了 EXEC 命令,所有的命令就都会被执行,即使此后客户端断线也没关系,因为Redis中已经记录了所有要执行的命令。

此外,Redis 的事务还能保证一个事务内的命令依次执行而不被其他命令插入。如果客户端A需要执行几条命令,同时客户端B发送了一条命令,如果不使用事务,则客户端B的命令可能会插入到客户端A的几条命令中执行。如果不希望发生这种情况,也可以使用事务。

和传统的事务不同的是,即使我们的加钱操作失败,我们也无法在这一组命令中让整个状态回滚到操作之前。Redis的事务没有关系数据库事务提供的回滚(rollback)功能。为此开发者必须在事务执行出错后自己收拾剩下的摊子(将数据库复原回事务执行前的状态等,这里我们一般采取日志记录然后业务补偿的方式来处理,但是一般情况下,在redis做的操作不应该有这种强一致性要求的需求,我们认为这种需求为不合理的设计)。

Redis提供了一个基于incr命令来操作一个整数型数值的原子递增功能,那么我们假设如果redis没有这个incr命令,我们该怎么实现这个incr的操作呢?那么我们下面的正主watch就要上场了。

利用watch命令可以监控一个或多个键,一旦其中有一个键被修改(或删除),之后的事务就不会执行。监控一直持续到EXEC命令(事务中的命令是在EXEC之后才执行的,所以在MULTI命令后可以修改WATCH监控的键值)。具体做法如下:

新代码在获取mykey的值之前先通过WATCH命令监控了该键,此后又将set命令包围在事务中,这样就可以有效的保证每个连接在执行EXEC之前,如果当前连接获取的mykey的值被其它连接的客户端修改,那么当前连接的EXEC命令将执行失败。这样调用者在判断返回值后就可以获悉val是否被重新设置成功。

由于WATCH命令的作用只是当被监控的键值被修改后阻止之后一个事务的执行,而不能保证其他客户端不修改这一键值,所以在一般的情况下我们需要在EXEC执行失败后重新执行整个函数。执行EXEC命令后会取消对所有键的监控,如果不想执行事务中的命令也可以使用UNWATCH命令来取消监控。

Redis还提供了实现一个hsetNX函数的功能:仅当字段存在时才赋值。为了避免竞态条件我们使用watch和事务来完成这一功能(伪代码)。在代码中会判断要赋值的字段是否存在,如果字段不存在的话就不执行事务中的命令,但需要使用UNWATCH命令来保证下一个事务的执行不会受到影响。

以上就是Redis的事务功能详解,希望能对你的开发有所帮助。