Redis(1.3)Redis的基本特性(事务、多数据库)
【1】两大特性
(1)多数据库
1个redis实例 可以有16个数据库,默认下标为0~15,默认连接到的是 0 下标的数据库。
(2)事务
【2】多数据库
【2.1】概念
1个redis实例 可以有16个数据库,默认下标为0~15,默认连接到的是 0 下标的数据库。
【2.2】基本操作
(1)select (切换数据库):select 1 把当前数据库切换到下标为 1 的数据库
(2)move(移动当前db下的 anykey 到其他 db):move nowdb_anykey new_db =》move a 1
(3)flushdb //清除当前数据库的所有 key
(4)flushall //清除所有数据库中的所有 key
【3】事务
【3.1】概念
所谓事务应具有以下特效:原子性(Atomicity), 一致性(Consistency),隔离性(Isolation),持久性(Durability),简称ACID,但redis所提供的事务比较简单,它通过MULTI、EXEC、DISCARD和WATCH等命令实现事务。
而Redis只支持简单的事务,将执行命令放入队列缓存,当程序中有异常或命令出错,执行DISCARD清空缓存队列不执行队列中命令,其事务过程有以下特点:
事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
事务是一个泛原子操作(这里我以泛原子称呼,在某些情况redis的事务不是原子性的,后续会说明):事务中的命令要么全部被执行,要么全部都不执行。
EXEC 命令负责触发并执行事务中的所有命令:
- 如果客户端在使用 MULTI 开启了一个事务之后,却因为断线而没有成功执行 EXEC ,那么事务中的所有命令都不会被执行。
- 另一方面,如果客户端成功在开启事务之后执行 EXEC ,那么事务中的所有命令都会被执行。
特别说明文中的泛原子操作:
- redis在开启事务以后,若执行命令具有显示的错误或者客户端中断则此次事务在执行EXEC命令时会调用DISCARD清空缓存队列不执行队列中的所有任务,此时是原子性的。
- (意思就是在multi 执行后,后面代码块输入出现语法错误,比如输入了一个不存在的命令等)
- 当执行命令过程中,命令没有显示的报错(例如LSET操作设置一个不存在的list),而是在EXEC调用时候某个命令出错,那么在这之前已经执行的命令将不会回滚,所以严格说来,redis并不支持原子性。
- (意思是在exec后,事务某一行有报错(比如操作的key不存在,比如给字符串做算术运算等),那么忽略改行,其他的继续运行)
与关系型数据库事务相比,
(1)multi:可以理解成关系型事务中的 begin
(2)exec :可以理解成关系型事务中的 commit
(3)discard :可以理解成关系型事务中的 rollback
【3.2】设计命令
MULTI #用于标记事务块的开始。Redis会将后续的命令逐个放入队列中,然后才能使用EXEC命令执行缓存队列中的命令。 EXEC #执行缓存队列中的命令 DISCARD #清除所有先前在一个事务中放入队列的命令,然后恢复正常的连接状态,如果使用了WATCH命令,那么DISCARD命令就会将当前连接监控的所有键取消监控。 WATCH key [key ...] #当某个事务需要按条件执行时,就要使用这个命令将给定的键设置为受监控的 UNWATCH #清除所有先前为一个事务监控的键,如果你调用了EXEC或DISCARD命令,那么就不需要手动调用UNWATCH命令
(1)multi:开启事务,把执行的命令添加串行化的命令队列中,直到执行exec。这些命令就会被原子化的执行了。
乐观锁机制
乐观锁:总是认为不会产生并发问题,每次去取数据的时候总认为不会有其他线程对数据进行修改,因此不会上锁,但是在更新时会判断其他线程在这之前有没有对数据进行修改,一般会使用版本号机制或检查再设置(CAS)操作实现。
redis通过WATCH命令实现乐观锁,作为WATCH命令的参数的键会受到Redis的监控,Redis能够检测到它们的变化。在执行EXEC命令之前,如果Redis检测到至少有一个键被修改了,那么整个事务便会中止运行,然后EXEC命令会返回一个nil值,提醒用户事务运行失败。
注意:WATCH命令需要在MULTI之前执行,不然redis会将其一个命令放入缓存队列中。
示例:在以下示例中通过一个客户端开启事务监听name键,另一个客户端在执行EXEC之前修改name键,此次事务将不会执行,并返回nil,如下。
原子性实践
为演示redis严格意义上将不支持原子性,做了一些简单实践。
从上面的结果可以看出,在开启事务前name 值为Rose,在开启事务先后执行了SET命令和LSET命令,但是LSET命令是错误的,当我们调用EXEC执行事务完事务以后,在回头看事务中的SET命令已经生效,并未回滚,因为在次过程中该命令没有显示的报错,所以可以说redis的事务不支持原子性。
参考:https://www.cnblogs.com/wdliu/p/9360286.html
Redis(1.3)Redis的基本特性(事务、多数据库)的更多相关文章
- Redis高级特性---------事务与持久化与发布订阅
一.redis事务的用法 1.开启事务:multi 2.提交事务:exec ( queued只是把指令放入队列中,没有执行) 3.取消事务:discard 4.redis事务不能保证同时成功或者失 ...
- redis 笔记06 发布与订阅、事务、慢查询日志、监视器
发布与订阅 1. 服务器状态在pubsub_channels字典保存了所有频道的订阅关系:SUBSCRIBE命令负责将客户端和被订阅的频道关联到这个字典里面,而UNSUBSCRIBE命令则负责 解除客 ...
- redis 在 php 中的应用(事务 [ Transaction ] 篇)
本文为我阅读了 redis参考手册 之后编写,注意 php_redis 和 redis-cli 的区别(主要是返回值类型和参数用法) 目录: Transaction(事务) WATCH UNWATCH ...
- Redis(二)-- 发布订阅、事务、安全、持久化
一.Redis发布订阅 Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. 打开两个窗口:session1 和 session2 在sess ...
- 架构师养成记--33.Redis哨兵、redis简单事务
Redis哨兵 有了主从复制,如果我想想对主从服务器进行监控,在redis2.6后提供了哨兵机制,2.6有哨兵1.0版本,并不稳定.2.8以后的哨兵功能才稳定起来. 顾名思义,哨兵就是监控Redis系 ...
- Redis数据类型、两种模型、事务、内部命令
1.redis数据类型 a.字符串,使用场景:常规key-value缓存应用 set name lixiang get name append name 123 # 字符串追加 mset key va ...
- Redis源代码分析(十七)--- multi事务操作
redis作为一非关系型数据库,居然相同拥有与RDBMS的事务操作,不免让我认为比較吃惊.在redis就专门有文件就是运行事务的相关操作的.也能够让我们领略一下.在Redis的代码中是怎样实现事务操作 ...
- Redis的消息订阅及发布及事务机制
Redis的消息订阅及发布及事务机制 订阅发布 SUBSCRIBE PUBLISH 订阅消息队列及发布消息. # 首先要打开redis-cli shell窗口 一个用于消息发布 一个用于消息订阅 # ...
- Redis 7.0 新功能新特性总览
说明:本文根据Redis 7 RC2 的release note 整理并翻译 近日,Redis 开源社区发布了7.0的两个预览版.在这两个预览版中,有很多Redis 7.0中新增加的特性,新增加的命令 ...
- Linux下安装Redis php-redis扩展 redis重启shell脚本 超详细!
前言 前面刚写过nosql其中三款热门产品的对比,这次主要写关于Redis的一些事情,Redis的介绍.安装以及扩展(php-redis,因为我是phper)安装等等.同时是写给我的朋友(cccjjj ...
随机推荐
- luogu 2577 [ZJOI2005]午餐 贪心+dp
发现让 $b$ 更大的越靠前越优,然后依次决策将每个人分给哪个窗口. 令 $f[i][j]$ 表示考虑了前 $i$ 个人,且第一个窗口的总等待时间为 $j$ 的最小总时间. 然后转移一下就好了~ #i ...
- free 内存检测
free打印出的内存信息主要分为两种,一种是安装的内存,一种是用磁盘虚拟的内存,就是这里的Swap,相信装过Linux系统的同学肯定不陌生交换分区,这里Swap大小就是我们分区的时候分配的大小. 下面 ...
- Mybatis-Plus BaseMapper自动生成SQL及MapperProxy
目录 Spring+Mybatis + Mybatis-Plus 自定义无XML的sql生成及MapperProxy代理生成 问题产生背景 框架是如何使用 无Xml的SQL是如何生成生成及SQL长成什 ...
- python排序之冒泡排序
def sort(list): for i in range(len(list)): for j in range(len(list) - i - 1): if list[j] < list[j ...
- Oracle中根据列名找到所属的表
oracle中如何根据一个字段名查找出所属的表名? 用如下语句, select * from user_tab_columns where column_name='列名', 例子:select * ...
- Qt Model/View 的简单说明
目录: (一) Qt Model/View 的简单说明 .预定义模型 (二)使用预定义模型 QstringListModel例子 (三)使用预定义模型QDirModel的例子 (四)Qt实现自定义模型 ...
- [Java]给指定时间加上十秒
package com.testEmp; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util. ...
- 性能测试 | Linux系统top命令中的io使用率,很多人都误解了它的具体含义
body{ text-align:left; width:80%; margin:10px 100px; } 最近在做连续数据流的缓冲系统,C语言代码实现后,粗略测试了下,功能上应该没有问题.那么,接 ...
- Linux下 安装jdk8
一.文件准备 1.1 文件名称 jdk-8u121-linux-x64.tar.gz 1.2 下载地址 http://www.oracle.com/technetwork/java/javase/do ...
- 传统Web应用请求和响应特点【显示当前时间】
(1)请求:浏览器以HTTP协议的方式提交请求到服务器 (2)响应:服务器以HTTP协议的方式响应内容到浏览器 注意:HTTP是WEB大众化非安全协议 HTTPS是WEB安全协议,是基于HTTP协议的 ...