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】

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

  1. Redis系列之key操作命令与Redis中的事务详解(六)

    序言 本篇主要目的有二: 1.展示所有数据类型中key的所有操作命令,以供大家学习,查阅,更深入的挖掘redis潜力. 2.掌握redis中的事务,让你的数据完整性一致性拥有更优的保障. redis命 ...

  2. Redis 中的事务

    Redis支持简单的事务 Redis与mysql事务的对比 Mysql Redis 开启 start transaction muitl 语句 普通sql 普通命令 失败 rollback 回滚 di ...

  3. redis中的事务

    首先明白在java中线程和进程的区别: 1.什么是多线程? 是指一个应用程序同时执行多个任务,一般来说一个任务就是一个线程 ,而一个应用程序有一个以上的线程我们称之为多线程. 2.什么是进程? 进程是 ...

  4. Redis 学习(三) —— 事务、消息发布订阅

    一.Redis事务 Redis 提供的事务机制与传统的数据库事务有些不同,传统数据库事务必须维护以下特性:原子性(Atomicity), 一致性(Consistency),隔离性(Isolation) ...

  5. Redis(十一):Redis的事务功能详解

    相关命令 1. MULTI 用于标记事务块的开始.Redis会将后续的命令逐个放入队列中,然后才能使用EXEC命令原子化地执行这个命令序列. 这个命令的运行格式如下所示: MULTI 这个命令的返回值 ...

  6. Redis数据库 02事务| 持久化| 主从复制| 集群

    1. Redis事务 Redis不支持事务,此事务不是关系型数据库中的事务: Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化.按顺序地执行.事务在执行的过程中,不会被其他客户端发送来的 ...

  7. 三、redis系列之事务

    1. 绪言 Redis也提供了事务机制,可以一次执行多个命令,本质是一组命令的集合.一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其他命令插入,不许加塞.但Redis对事务的支持是部分支持 ...

  8. redis的简单事务

    Redis对事务的支持目前还比较简单.Redis只能保证一个client发起的事务中的命令可以连续的执行,而中间不会插入其他client的命令.当一个client在一个连接中发出multi命令时,这个 ...

  9. 高并发场景系列(一) 利用redis实现分布式事务锁,解决高并发环境下减库存

    原文:http://blog.csdn.net/heyewu4107/article/details/71009712 高并发场景系列(一) 利用redis实现分布式事务锁,解决高并发环境下减库存 问 ...

  10. redis中的事务(版本2.6.16)

    一.命令支持 1.multi 开始事务 2.exec事务提交 3.取消事务discard 二.事务示例 1.示例 redis>set key1 20OKredis>mutilOKredis ...

随机推荐

  1. cardlayout

    import javax.swing.*;import java.awt.*;import java.awt.event.*;public class demo_9{    public static ...

  2. 编译安装php5.6

    sudo yum -y install curl-devel  bzip2 bzip2-devel libxml2  libxml2-devel  libjpeg libpng freetype li ...

  3. LoadRunner简单介绍----性能自动化测试工具

    在做性能测试中,我认为技术可以说是武功心法,工具则是一把利剑,有一把好的利剑可以帮助自己更好的完成性能测试工作.在这里简单介绍一下LoadRunner,带大家一起来认识一下这把尚方宝剑. 一.性能测试 ...

  4. 初步了解学习flask轻量级框架,

    关于flask我有话说 flask作为一个轻量级框架,它里面有好多扩展包需要下载,比较麻烦,而且有的时候flask需要在虚拟环境下运行,但是他的优点还是有滴 ,只要是用过Django的人,都会觉得fl ...

  5. Python19/1/11--标签与过滤器/Django模块导入继承/静态文件配置

      1 模板语言之变量: -{{ }} 相当于执行了print -深度查询 . 如果是方法,不能加括号,不能传参数2 过滤器 {{ 变量|过滤器的名字:'参数' }} -add -default -s ...

  6. Hibernate中的实体规则、对象状态和进阶-一级缓存

    一.hibernate中的实体规则 1.实体类创建的注意事项 2.主键类型 3.主键生成策略 (1)代理主键 (2)自然主键 二.hibernate中的对象状态 1.对象分为三种状态 2.三种状态的转 ...

  7. CentOS 6下升级Python版本

    CentOS6.8默认的python版本是2.6,而现在好多python组件开始只支持2.7以上的版本,比如说我今天遇到的pip install pysqlite,升级python版本是一个痛苦但又常 ...

  8. JDBC&Oracle启动

    [Wed Apr 26 2017 16:05:11 GMT+0800]PLSQL Developer连接远程oracle配置(本地不安装客户端).在windows机器上不想安装oracle或者orac ...

  9. Python基础-数据类型-转摘

    1.数字 2 是一个整数的例子.长整数 不过是大一些的整数.3.23和52.3E-4是浮点数的例子.E标记表示10的幂.在这里,52.3E-4表示52.3 * 10-4.(-5+4j)和(2.3-4. ...

  10. <笔记>字体文件的路径问题

    如果做过虚拟域名,不可以通过127.0.0.1来访问字体文件 改成通过虚拟域名访问,就没问题: 不过更建议使用相对路径