Redis(3)---Redis事务

Redis事务

Redis 通过 MULTI 、EXEC、 DISCARD  和 WATCH 四个命令来实现事务功能。

MULTI :标记一个事务块的开始。

EXEC: 执行所有事务块内的命令。

DISCARD :取消事务,放弃执行事务块内的所有命令。

WATCH key [key ...] :监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。

一、事务

1、是什么?

可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,不许加塞!

   2、能干什么?

一个队列中,一次性的、顺序性的、排他性的执行一系列的命令。要么一起成功,要么一起失败。排好队,一次性的执行多个redis的命令!

   3、怎么玩?

通过MULTI指令开启,之后输入多个命令!Redis将它们加入到队列当中,所有的命令通过EXEC来开启执行!通过DISCARD来放弃本次的批处理操作!

(1)正常执行(好比购物先加入购物车,最后EXEC统一结账。)

192.168.1.66:6379> MULTI    --开启事务
OK
192.168.1.66:6379> set k1 v1
QUEUED
192.168.1.66:6379> set k2 v2
QUEUED
192.168.1.66:6379> set k3 v3
QUEUED
192.168.1.66:6379> set k4 v4
QUEUED
192.168.1.66:6379> get k2
QUEUED
192.168.1.66:6379> EXEC  --结束事务
1) OK
2) OK
3) OK
4) OK
5) "v2"

(2)DISCARD 撤销所有操作!

192.168.1.66:6379> MULTI
OK
192.168.1.66:6379> set k1 11
QUEUED
192.168.1.66:6379> set k2 22
QUEUED
192.168.1.66:6379> set k3 33
QUEUED
192.168.1.66:6379> DISCARD
OK
192.168.1.66:6379> get k1  --这里的k1的value值还是上面的值,而不是新设置的value值
"v1"    

(3)加入队列时不出错,下面的都将正常运行,执行时出错不影响其他语句!

192.168.1.66:6379> set k1 v1
OK
192.168.1.66:6379> set k2 v2
OK
192.168.1.66:6379> MULTI
OK
192.168.1.66:6379> incr k1
QUEUED
192.168.1.66:6379> set k2 22
QUEUED
192.168.1.66:6379> EXEC
1) (error) ERR value is not an integer or out of range --在运行是才发现k1不是数字,报错
2) OK     --执行成功

注意:
   (1)当遇到执行错误时,redis放过这种错误,保证事务执行完成。(所以说redis的事务并不是保证原子性)
   (2)与mysql中事务不同,在redis事务遇到执行错误的时候,不会进行回滚,而是简单的放过了,并保证其他的命令正常执行。这个区别在实现业务的时候,需要自己保证逻辑符合预期。
   (3)当事务的执行过程中,如果redis意外的挂了。很遗憾只有部分命令执行了,后面的也就被丢弃了。当然如果我们使用的append-only file方式持久化,redis会用单个write操作写入整个事务内容。即是是这种方式还是有可能只部分写入了事务到磁盘。发生部分写入事务的情况 下,redis重启时会检测到这种情况,然后失败退出。可以使用redis-check-aof工具进行修复,修复会删除部分写入的事务内容。修复完后就 能够重新启动了。

二、WATCH

WATCH 命令可以为 Redis 事务提供 check-and-set (CAS)行为。

被 WATCH 的键会被监视,并会发觉这些键是否被改动过了。 如果有至少一个被监视的键在 EXEC 执行之前被修改了, 那么整个事务都会被取消, EXEC 返回空多条批量回复(null multi-bulk reply)来表示事务已经失败。

1、首先我们不加WATCH进行事务处理


时间


客户端 A


客户端 B


说明


T1


SET name aa

SET age  10


GET name

aa

GET age

10


数据库中两客户端登录,及键初始值。

它们是同步的。


T2


MULTI

SET name bb

Incr age

 
此时,客户端1开启事务,并提交队列命令:

1.想要将当前age自增+1运算;

2.将name值改为bb


T3

 
SET name cc

Incr age


此时,客户端2修改了age值

同时修改name值为cc


T4


EXEC

 

T5


GET name

bb

GET age

12


此时,客户端1执行队列命令,发现运算之后age不是理想中的11,而是12原因是被其它客户插足抢先给修改了。name值确实是没有被其它所改变。这样可能导致数据不一致性。

2、添加WARCH

客户端1-引入“乐观锁”机制 客户端2 说明
 SET age
"10"
 SET name
"zhangsan"

 GET age
"10"
 GET name
"zhangsan"
数据库中两客户端登录,及键初始值。
 WATCH    age name
OK
 MUTLI
OK
 incr age
QUEUED
 set name lisi
QUEUED
  此时,客户端1用watch命令监视age和name,然后开启事务,并提交队列命令
   incr age
(integer) 11
此时,客户端2修改了age值
 exec
(nil)
 get age
"11"
 get name
"zhangsan"
  此时,客户端1执行队列命令,由watch监控发现此期间age的值已经被修改过,则让事整个务回滚,不做任何动作。

watch可以同时监控多个键,在监控期间只要有一个键被其它客户端改变,则整个事务回滚。

想太多,做太少,中间的落差就是烦恼。想没有烦恼,要么别想,要么多做。少校【1】

原文地址:https://www.cnblogs.com/qdhxhz/p/9135684.html

时间: 2024-11-05 15:53:58

Redis(3)---Redis事务的相关文章

Redis 中的事务

Redis支持简单的事务 Redis与mysql事务的对比 Mysql Redis 开启 start transaction muitl 语句 普通sql 普通命令 失败 rollback 回滚 discard 取消 成功 commit exec 注: rollback与discard 的区别 如果已经成功执行了2条语句, 第3条语句出错. Rollback后,前2条的语句影响消失. Discard只是结束本次事务,前2条语句造成的影响仍然还在 注: 在mutil后面的语句中, 语句出错可能有2

redis学习(5) - 事务

1.redis中的事务是一组命令的集合.一个事务中的命令,要么都执行,要么都不执行 2. MULTI    告诉redis:下面我发给你的命令属于同一个事务,先不要执行,而是把它们暂时存起来 OK SADD "user:1:followers" 2   发送命令 QUEUED                返回QUEUED表示这两条命令已经进入等待执行的事务队列中了 SADD "user:2:followers" 1 QUEUED EXEC            

redis watch 加 事务实现秒杀

<?php //redis watch 加 事务实现秒杀  $redis = new redis();  $result = $redis->connect('10.10.10.119', 6379); $redis->watch("mywatchkey"); //必须先watch 后get $mywatchkey = $redis->get("mywatchkey"); $rob_total = 100;   //抢购数量 if($mywa

Redis教程6--Redis事务

redis对事务的支持目前还比较简单.redis只能保证一个client发起的事务中的命令可以连续的执行,而中间不会插入其他client的命令. 由于redis是单线程来处理所有client的请求的所以做到这点是很容易的.一般情况下redis在接受到一个client发来的命令后会立即处理并 返回处理结果,但是当一个client在一个连接中发出multi命令有,这个连接会进入一个事务上下文,该连接后续的命令并不是立即执行,而是先放到一 个队列中.当从此连接受到exec命令后,redis会顺序的执行

redis代码解析-事务

redis 的事务相关的几个命令分别为 watch multi exec. watch 可以监控一个变量在事务开始执行之前是否有被修改.使用方式为: WATCH key [key ...] 在redis内部的实现是每个db有一个名为watched_keys的dict,这个dict的key为监控的key,value为所有监控该key的client组成的链表. 所有的涉及到修改数据库的命令执行成功之后都会执行signalModifiedKey->touchWatchedKey,将修改的db中的wat

八、Redis 中的事务

Redis支持简单的事务 Redis与 mysql事务的对比 Mysql Redis 开启 start transaction multi 语句 普通sql 普通命令 失败 rollback 回滚 discard 取消 成功 commit exec 注: rollback与discard 的区别 如果已经成功执行了2条语句, 第3条语句出错. Rollback后,前2条的语句影响消失. Discard只是结束本次事务,前2条语句造成的影响仍然还在 注: 在mutil后面的语句中, 语句出错可能有

Redis篇5-redis事务

概述 官方说明:https://redis.io/topics/transactions redis"部分"支持事务(部分回滚) 关键命令 MULTI 开始事务 EXEC 开始执行事务内命令s DISCARD 取消事务并放弃事务内命令s的执行 WATCH 监视一个或多个key,开始乐观锁CAS的事务操作 UNWATCH 取消所有key监视 从Redis2.2开始支持用于乐观锁的check-and-set (CAS) 开始使用 multi-exec正常提交 mset k1 v1 k2 v

04: redis 消费模式 和 事务 - 扩展slow日志

Redis发布消息模式 生产消费模型 Redis发布消息通常有两种模式: 1:队列模式(queuing) 2:发布-订阅模式(publish-subscribe) 任务队列:顾名思义,就是“传递消息的队列”.与任务队列进行交互的实体有两类,一类是生产者(producer),另一类则是消费者(consumer).生产者将需要处理的任务放入任务队列中,而消费者则不断地从任务独立中读入任务信息并执行. 任务队列的好处: 松耦合. 生产者和消费者只需按照约定的任务描述格式,进行编写代码. 易于扩展. 多

【redis】-- redis的事务

目录 1.redis事务的执行流程 2.事务开始 3.命令入队 事务队列 4.命令的执行 5.watch命令 6.放弃事务(DISCARD) 7.事务的ACID属性 1.原子性 redis不支持回滚 redis不支持事务回滚的原因: 2.一致性 3.隔离性 4.持久性 Redis通过MULTI.EXEC.WATCH等命令来实现事务( transaction)功能.事务提供了一种将多个命令请求打包,然后- -次性.按顺序地执行多个命令的机制,并且在事务执行期间,服务器不会中断事务而改去执行其他客户

Redis中的事务(多命令)操作

作为一个nosql数据库,事务是必要功能.但是redis我们是可以理解为它不支持事务操作的,因为它的特征完全不满足我们对事物的正常理解 ps:我不知道是谁一开始提出redis支持事务的,但是我更倾向于这是redis的多命令功能 multi这个命令单词意思已经说明了一切,我只能理解为中文文档一厢情愿了 事务的使用 1. 开启事务 命令:multi 127.0.0.1:6379> multi OK 执行该命令后,连接会进入事务模式 2.执行操作 可以执行任意的redis数据操作命令,那么执行操作会进