1、事务的定义

Redis的事务提供了一种“将多个命令打包, 然后一次性、按顺序地执行”的机制。

redis事务的主要作用就是串联多个命令防止别的命令插队。

但是,事务并不具有传统数据库事务的特性,如回滚。

2、事务命令

Redis中的事务可以通过以下命令来执行:

  • MULTI:用于开启一个事务块,表示之后的命令将被放入事务队列中,但并不会立即执行。
  • 事务命令:在MULTIEXEC之间的所有命令都将被添加到事务队列中。
  • EXEC:用于执行事务队列中的所有命令。执行事务后,事务队列会被清空。
  • DISCARD:用于取消事务,清空事务队列中的命令。
  • WATCH:监视一个或多个键,当被监视的键被修改时,事务将被打断。

Redis事务分2个阶段:组队/打包阶段、执行阶段

  • 组队/打包阶段:将所有命令加入命令队列
  • 执行阶段:依次执行队列中的命令,期间不会被其他客户端发送的请求命令插队或打断。

示例:

redis 127.0.0.1:6379> MULTI
OK
redis 127.0.0.1:6379> SET book-name "Redis从入门到放弃"
QUEUED
redis 127.0.0.1:6379> GET book-name
QUEUED
redis 127.0.0.1:6379> SADD tag "Redis" "入门" "放弃"
QUEUED
redis 127.0.0.1:6379> SMEMBERS tag
QUEUED
redis 127.0.0.1:6379> EXEC
1) OK
2) "Redis从入门到放弃"
3) (integer) 3
4) 1) "Redis"
2) "入门"
3) "放弃"

3、事务错误处理

事务错误处理方式分为两个阶段:组队时错误执行时错误

  • 组队时错误:如果在组队过程中出现错误,整个队列中的所有命令都将被取消。

  • 执行时错误:如果在执行阶段出现错误,会导致部分命令执行成功,部分命令执行失败。

4、事务的冲突问题

为了解决事务的冲突问题,可以使用锁,包括悲观锁和乐观锁。

4.1、悲观锁(Pessimistic Lock)

悲观锁是一种对数据修改持有悲观态度的并发控制方式。它总是假设最坏的情况,每次读取数据时都默认其他线程会更改数据,因此需要加锁操作。

悲观锁的实现:

  • 传统的关系型数据库使用这种锁机制,比如行锁、表锁、读锁、写锁等,都是在操作之前先上锁。
  • Java 里面的同步 synchronized 关键字的实现。

4.2、乐观锁(Optimistic Locking)

乐观锁相对于悲观锁而言,它假设数据一般情况下不会造成冲突,只在数据提交更新时才检测是否冲突。如果冲突,则返回异常信息,让用户决定如何处理。乐观锁适用于读多写少的场景,可以提高程序吞吐量。

乐观锁的实现:

  • CAS 实现:Java 中java.util.concurrent.atomic包下面的原子变量使用了乐观锁的一种 CAS 实现方式。
  • 版本号控制:一般是在数据表中加上一个数据版本号 version 字段,表示数据被修改的次数。当数据被修改时,version 值会 +1。当线程 A 要更新数据时,在读取数据的同时也会读取 version 值,在提交更新时,若刚才读取到的 version 值与当前数据库中的 version 值相等时才更新,否则重试更新操作,直到更新成功。

Redis通过CAS (Check and Set) 实现乐观锁,使用WATCH指令监听一个或多个键,当用户提交修改事务时,会检查监听的键是否发生变化。若没有发生变化,则提交成功;否则,事务失败。

例如,两个客户端在同一时间开始一个事务,他们都对同一个键的值进行了修改,但在执行事务的EXEC命令时,只能有一个客户端的事务能够成功,另一个客户端的事务会因为键的值发生了改变而执行失败。

客户端1:

# 刷新数据库
127.0.0.1:6379> FLUSHDB
OK
# 设置key值
127.0.0.1:6379> set key 10
OK
# 监听key
127.0.0.1:6379> WATCH key
OK
# 开启事务
127.0.0.1:6379> MULTI
OK

客户端2:

# 监听key
127.0.0.1:6379> WATCH key
OK
# 开启事务
127.0.0.1:6379> MULTI
OK

客户端1:

# 指令加入队列
127.0.0.1:6379(TX)> INCR key
QUEUED
# 执行指令,可以看到执行成功,修改了一条数据,值被更新为11
127.0.0.1:6379(TX)> EXEC
1) (integer) 11

客户端2:

127.0.0.1:6379(TX)> INCR key
QUEUED
127.0.0.1:6379(TX)> exec
(nil)

5、事务三特性

Redis事务具有以下三个特性:

  1. 单独的隔离操作:事务中的命令会被序列化并按顺序执行,不会被其他客户端的指令打断。
  2. 没有隔离级别的概念:事务提交前所有指令都不会被执行。
  3. 无原子性:事务组队时具有原子性,但在执行阶段出错某段指令,事务过程中的指令仍然会生效。

Redis从入门到放弃(5):事务的更多相关文章

  1. Redis 从入门到放弃

    Redis 从入门到放弃 http://www.iocoder.cn/Fight/Redis-went-from-getting-started-to-quitting/

  2. redis从入门到放弃 -> 简介&概念

    一.redis简介 Redis是一款开源的.高性能的键-值存储.它常被称作是一款数据结构服务器. 当值支持的主要数据类型为:字符串(strings)类型,括哈希(hashes).列表(lists).集 ...

  3. Redis——从入门到放弃

    redis简介 Redis is an open source (BSD licensed), in-memory data structure store, used as a database, ...

  4. redis从入门到放弃 -> 部署方案

    单点部署方案 环境准备: [root@localhost ~]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) [root@ ...

  5. spring入门到放弃——spring事务管理

    Spring事务提供了两种管理的的方式:编程式事务和声明式事务 简单回顾下事务: 事务:逻辑上的一组操作,组成操作的各个单元,要么全部成功,要么全部失败. 事务特性: 原子性:一个事务包含的各个操作单 ...

  6. CYQ.Data 从入门到放弃ORM系列:开篇:自动化框架编程思维

    前言: 随着CYQ.Data 开始回归免费使用之后,发现用户的情绪越来越激动,为了保持这持续的激动性,让我有了开源的念头. 同时,由于框架经过这5-6年来的不断演进,以前发的早期教程已经太落后了,包括 ...

  7. 分布式缓存技术redis学习系列(三)——redis高级应用(主从、事务与锁、持久化)

    上文<详细讲解redis数据结构(内存模型)以及常用命令>介绍了redis的数据类型以及常用命令,本文我们来学习下redis的一些高级特性. 安全性设置 设置客户端操作秘密 redis安装 ...

  8. 超强、超详细Redis数据库入门教程

    这篇文章主要介绍了超强.超详细Redis入门教程,本文详细介绍了Redis数据库各个方面的知识,需要的朋友可以参考下 [本教程目录] 1.redis是什么2.redis的作者何许人也3.谁在使用red ...

  9. 分布式缓存技术redis学习(三)——redis高级应用(主从、事务与锁、持久化)

    上文<详细讲解redis数据结构(内存模型)以及常用命令>介绍了redis的数据类型以及常用命令,本文我们来学习下redis的一些高级特性.目录如下: 安全性设置 设置客户端操作秘密 客户 ...

  10. redis 学习笔记——数据同步、事务

    redis主从同步      redis支持简单易用的主从复制(master-slave replication)功能,该功能也是redis高可用性实现的基础.   redis复制原理      re ...

随机推荐

  1. Windows屏幕解锁服务原理及实现(1)

    https://github.com/zk2013/windows_remote_lock_unlock_screen 将生成的DLL注册至注册表 HKEY_LOCAL_MACHINE\SOFTWAR ...

  2. 【问题排查篇】一次业务问题对 ES 的 cardinality 原理探究

    作者:京东科技 王长春 业务问题 小编工作中负责业务的一个服务端系统,使用了 Elasticsearch 服务做数据存储,业务运营人员反馈,用户在使用该产品时发现,用户后台统计的订单笔数和导出的订单笔 ...

  3. celery+Rabbit MQ简单的Demo

    介绍 一个简单的celery + rabbitmq 的搭建例子,用于记录 Celery 异步处理框架, 安装命令 pip install celery RabbitMQ 消息中间件,用来做队列 安装配 ...

  4. 2022-08-14:k8s安装PostgreSQL,yaml如何写?

    2022-08-14:k8s安装PostgreSQL,yaml如何写? 答案2022-08-14: yaml如下: apiVersion: apps/v1 kind: Deployment metad ...

  5. 2022-07-06:以下go语言代码是否会panic?A:会;B:不会。 package main import “C“ func main() { var ch chan struct

    2022-07-06:以下go语言代码是否会panic?A:会:B:不会. package main import "C" func main() { var ch chan st ...

  6. 2021-05-14:给定一个数组arr,想知道arr中哪两个数的异或结果最大。返回最大的异或结果。

    2021-05-14:给定一个数组arr,想知道arr中哪两个数的异或结果最大.返回最大的异或结果. 福大大 答案2021-05-14: 前缀树.一个数,用二进制表示,0走左边分支,1走右边分支.准备 ...

  7. Django4全栈进阶之路7 makemigrations和migrate迁移

    Django 4 中使用数据迁移(migration)来管理数据库结构的变化.数据迁移可以创建.修改和删除数据库表.字段.索引等对象,以及填充初始数据. 下面是使用数据迁移的基本步骤: 1.在 app ...

  8. Django context must be a dict rather than UserProfile.

    context must be a dict rather than UserProfile. # 主页@login_requireddef index(request): data={} data ...

  9. 10 款 VS Code 插件神器,第 7 款超级实用!

    VS Code 是这两年非常热门的一款 IDE,它不仅有提升开发体验的界面.轻量化的编辑器,还有丰富而强大的插件,这些优秀的插件使得 VS Code 生态体系更加吸引人,让开发效率大大提升.本文来介绍 ...

  10. SQL Server 2008/2012 完整数据库备份+差异备份+事务日志备份 数据库完整还原(一)

    还原方案 数据库级(数据库完整还原) 还原和恢复整个数据库.数据库在还原和恢复操作期间会处于离线状态.SQL SERVER不允许用户备份或还原单个表.还原方案是指从一个或多个备份中还原数据.继而恢复数 ...