Gitlib Gitlib
首页
  • 分类
  • 标签
  • 归档
  • Golang开发实践万字总结
  • MySQL核心知识汇总
  • Redis实践总结
  • MQ实践万字总结
  • Docker数据持久化总结
  • Docker网络模式深度解读
  • 常用游戏反外挂技术总结
  • 读书笔记
  • 心情杂货
  • 行业杂谈
  • 友情链接
关于我
GitHub (opens new window)

Ravior

以梦为马,莫负韶华
首页
  • 分类
  • 标签
  • 归档
  • Golang开发实践万字总结
  • MySQL核心知识汇总
  • Redis实践总结
  • MQ实践万字总结
  • Docker数据持久化总结
  • Docker网络模式深度解读
  • 常用游戏反外挂技术总结
  • 读书笔记
  • 心情杂货
  • 行业杂谈
  • 友情链接
关于我
GitHub (opens new window)
  • 操作系统

  • 计算机网络

  • 数据结构和算法

  • MySQL

  • Redis

    • Redis持久化和数据数据恢复
    • Redis发布订阅
    • Redis管道技术
    • Redis事务机制
      • Watch
    • Redis数据过期和淘汰策略
    • Redis中BitMap使用
    • Redis中lua脚本使用
    • Redis通信协议(RESP)入门
    • Redis性能测试Redis-benchmark
    • Redis主从模式搭建及应用
    • Redis集群及高可用实现
    • Redis和Memcache对比
    • Redis缓存穿透、缓存击穿、缓存雪崩
    • Redis万字总结
    • 如此简单:Redis安装
    • Memcached安装部署
  • Nginx

  • MongoDB

  • 其他

  • 计算机基础
  • Redis
Ravior
2018-12-01
目录

Redis事务机制

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

在Redis中实现事务主要依靠以下几个命令来实现:

Redis事务

Redis事务从开始到结束通常会通过三个阶段:

  • 开始事务
  • 命令入队
  • 执行事务

以PHP语言开发为例:

$redis = new Redis();

$redis->connect('127.0.0.1',6379);

// 开启事务
$redis->multi();
$redis->setex('keyTest', 60, 1);
$redis->get('keyTest');
$redis->incr('keyTest');
$redis->get('keyTest');
// 执行事务,$ret为一次执行的结果数组
$ret = $redis->exec();
1
2
3
4
5
6
7
8
9
10
11
12

有几点需要注意:

  • Redis事务没有隔离级别的概念

批量操作在发送 EXEC 命令前被放入队列缓存,并不会被实际执行,也就不存在事务内的查询要看到事务里的更新,事务外查询不能看到。

  • Redis不保证原子性

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

  • Redis事务不支持回滚

Redis的事务没有关系数据库事务提供的回滚(rollback) 功能。为此开发者必须在事务执行出错后自己收拾剩下的摊子。

# Watch

Redis使用WATCH命令实现事务的“检查再设置”(CAS)行为,WATCH命令可以监控一个或多个键,一旦其中有一个键被修改(或删除),之后的事务就不会执行。监控一直持续到EXEC命令(事务中的命令是在EXEC之后才执行的,所以在MULTI命令后可以修改WATCH监控的键值)。

具体做法如下:

 WATCH mykey
 val = GET mykey
 val = val + 1
 MULTI
 SET mykey $val
 EXEC
1
2
3
4
5
6

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

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


参考文档:

  • PHP使用Redis的Transaction(事务)命令 (opens new window)
#Redis
上次更新: 2022/12/01, 11:09:34
Redis管道技术
Redis数据过期和淘汰策略

← Redis管道技术 Redis数据过期和淘汰策略→

最近更新
01
常用游戏反外挂技术总结
11-27
02
Golang开发实践万字总结
11-11
03
Redis万字总结
10-30
更多文章>
Theme by Vdoing | Copyright © 2011-2022 Ravior | 粤ICP备17060229号-3 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式