Redis事务及锁应用
Redis只支持简单的事务,不像mysql那样比较完整严格,对数据的完整性也维持的很好。redis的开启事务实际上只是将开启事务之后的一段命令用队列
包裹起来了,当调用redis的执行命令(exec)全部执行在队列中的命令。
一、mysql事务与redis事务的比较
|
Mysql |
Redis |
|
|
开启 |
start transaction |
multi |
|
语句 |
普通sql |
普通命令 |
|
失败 |
rollback 回滚 |
discard 取消 |
|
成功 |
commit |
exec |
二、redis事务一般使用演示
(1).先清空所有数据
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set t1 "test1 value"
QUEUED
127.0.0.1:6379> set t2 "test2 value"
QUEUED
127.0.0.1:6379>
(2).当没有执行提交的时,打开另外一个redis命令窗口执行keys *发现并没有新的数据产生
127.0.0.1:6379> keys *
(empty list or set)
(3).在窗口一种执行提交
127.0.0.1:6379> exec
1) OK
2) OK
(4).另一窗口显示所有key
127.0.0.1:6379> keys *
1) "t1"
2) "t2"
三、redis事务若是出错并不回滚
redis事务命令列中如果出错,整个事务并不回滚,而是会继续执行下去,所以这就违反了事务中ACID特点的原子性
redis事务出错的两种情况:
(1).redis语法有问题导致出错
执行exec后的结果:所有multi后执行的命令都不会被执行
演示如下:
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set a a
QUEUED
127.0.0.1:6379> set b
(error) ERR wrong number of arguments for 'set' command
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379>
查看最终结果key:
127.0.0.1:6379> keys *
1) "t1"
2) "t2"
总结:并没有找到multi后执行的命令结果key,说明全部失败了
(2).redis语法没问题但是操作的适用对象有问题,比如sadd(设置set类型的值)操作string类型的key
执行exec的结果:除了redis语法操作的命令不被正确执行,其它不会被影响正常执行(这个是属于程序级别的出错,一般是由程序员控制的)
演示如下:
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> set num1 3
OK
127.0.0.1:6379> set num2 4
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incrby num1 3
QUEUED
127.0.0.1:6379> sadd num2 2
QUEUED
127.0.0.1:6379> exec
1) (integer) 6
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
查看最终结果:
127.0.0.1:6379> mget num1 num2
1) "6"
2) "4"
127.0.0.1:6379>
总结:因为num1,num2都是字符串类型,multi后用sadd操作num2类型错误,而最终执行后只是num2执行失败,num2正常的由数字3增加了3变成了六。
四、redis的锁机制
悲观锁:如果我去买票,我会想世界不和谐,肯定有人跟我抢,我先把票锁起来,只有我能够操作,这就是悲观锁
乐观锁:如果我去买票,哎呀没那么多人买票,还有好多的票了,所以不用上锁,我只需要关注最后剩下多少张票就行了,这就是乐观锁
演示如下
127.0.0.1:6379> keys *
(empty list or set)
如果售票点有1张票,自己手上还有100块钱
127.0.0.1:6379> set ticket 1
OK
127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> mget ticket money
1) "1"
2) "100"
我们先给ticket(票)加锁
127.0.0.1:6379> watch ticket
OK
开始执行事务
127.0.0.1:6379> multi
OK
这个时候火车站只有一张余票了,我发起了两张票的请求
127.0.0.1:6379> decrby ticket 2
QUEUED
扣除80块的票钱
127.0.0.1:6379> decrby money 80
QUEUED
开始执行提交
127.0.0.1:6379> exec
报错了
(error) EXECABORT Transaction discarded because of previous errors.
查看结果没有变化因为票只有一张不够所以整个事务保持原有的结果
127.0.0.1:6379> mget ticket money
1) "1"
2) "100"
unwatch取消所有锁监听
127.0.0.1:6379> unwatch
OK
总结:redis的事务中,启用的是乐观锁,只负责事务中key没有被改动。
Redis事务及锁应用的更多相关文章
- redis事务,分布式锁
事务:一组命令集合 主要命令multi 和exec multi set a 1 sadd s1 a ...... exec 错误处理 (1)语法错误 127.0.0.1:6379> multi ...
- redis 事务(悲观锁和乐观锁)
MULTI 开启事务,后续的命令会被加入到同一个事务中 事务中的操作会发送给客服端,但是不会立即执行,而是将操作放到了该事务对应的一个队列中,服务端返回QUEQUD EXEC 执行EXEC后,事务中的 ...
- 分布式缓存技术redis学习系列(三)——redis高级应用(主从、事务与锁、持久化)
上文<详细讲解redis数据结构(内存模型)以及常用命令>介绍了redis的数据类型以及常用命令,本文我们来学习下redis的一些高级特性. 安全性设置 设置客户端操作秘密 redis安装 ...
- 分布式缓存技术redis学习(三)——redis高级应用(主从、事务与锁、持久化)
上文<详细讲解redis数据结构(内存模型)以及常用命令>介绍了redis的数据类型以及常用命令,本文我们来学习下redis的一些高级特性.目录如下: 安全性设置 设置客户端操作秘密 客户 ...
- Redis事务和分布式锁
Redis事务 Redis中的事务(transaction)是一组命令的集合.事务同命令一样都是Redis最小的执行单位,一个事务中的命令要么都执行,要么都不执行.Redis事务的实现需要用到 MUL ...
- 分布式缓存技术redis系列(三)——redis高级应用(主从、事务与锁、持久化)
上文<详细讲解redis数据结构(内存模型)以及常用命令>介绍了redis的数据类型以及常用命令,本文我们来学习下redis的一些高级特性. 安全性设置 设置客户端操作秘密 redis安装 ...
- 一篇和Redis有关的锁和事务的文章
部分参考链接 Transaction StackExchange.Redis Transaction hashest 正文 Redis 是一种基于内存的单线程数据库.意味着所有的命令是一个接一个的执行 ...
- redis 事务 & 锁
参考:https://www.cnblogs.com/DeepInThought/p/10720132.html Redis不保证原子性:Redis中,单条命令是原子性执行的,但事务不保证原子性,且没 ...
- redis事务机制和分布式锁
Redis事务机制 严格意义来讲,Redis的事务和我们理解的传统数据库(如mysql)的事务是不一样的:Redis的事务实质上是命令的集合,在一个事务中要么所有命令都被执行,要么所有事物都不执行. ...
随机推荐
- ADO.NET简介
一.ADO.NET ADO.NET源起ADO(ActiveX Data Objects),是一个COM组件库,在NET编程环境中优先使用的数据访问接口, 提供对诸如 SQL Server 和 XML ...
- Java复习5.面向对象
Java 复习5面向对象知识 20131004 前言: 前几天整理了C++中的面向对象的知识,学习Java语言,当然最重要的就是面向对象的知识,因为可以说Java是最正宗的面向对象语言,相比C++,更 ...
- Mysqlde的权限操作,以及增加用户
增加用户及直接授权 ' 在这条命令里边all代表所有的权限,*.*代表所有的空间名.表名 sql的通配符 _ 代表任意的一个字符 % 代表任意的字符的任意长度 修改用户的密码 update 空间名.表 ...
- PHP获取日期对应星期、一周日期、星期开始与结束日期的方法
本文实例讲述了PHP获取日期对应星期.一周日期.星期开始与结束日期的方法.分享给大家供大家参考,具体如下: /* * 获取日期对应的星期 * 参数$date为输入的日期数据,格式如:2018-6-22 ...
- zset类型以及其操作
sorted set类型 sorted sets类型以及其操作zset是set的一格升级版本,它在set的基础上增加了一格顺序属性,这一属性在添加元素的同时可以指定,每次指定后,zset会自动重新按照 ...
- 剑指offer--49.矩阵中的路径
时间限制:1秒 空间限制:32768K 热度指数:156998 题目描述 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一个格子开始,每一步可以在矩 ...
- PostgreSQL文档编译
之前一直没有将doc进行编译,最近编译成功了,却无法用man来查看,发现是没有将man的目录添加到搜索路径: MANPATH /usr/pgsql-10/share/man 加入到 /etc/man. ...
- JAVA交换两个变量的值-(不使用第三变量)
以下方法的根本原理就是: 借助第三个变量 c = a; a = b; b = c; 运算符-不借助第三变量: a = a+b; b = a-b; a = a-b; 为运算符-不借助第三个变量: (此种 ...
- 【干货】Kaggle 数据挖掘比赛经验分享(mark 专业的数据建模过程)
简介 Kaggle 于 2010 年创立,专注数据科学,机器学习竞赛的举办,是全球最大的数据科学社区和数据竞赛平台.笔者从 2013 年开始,陆续参加了多场 Kaggle上面举办的比赛,相继获得了 C ...
- IOS开发 多线程编程 - NSOperation
一.NSOperation 1.简介 NSOperation实例封装了需要执行的操作和执行操作所需的数据,并且能够以并发或非并发的方式执行这个操作. NSOperation本身是抽象基类,因此必须使用 ...