Redis之品鉴之旅(五)
Redis事务
- 原子性:就是最小的单位
- 一致性:好多命令,要么全部执行成功,要么全部执行失败
- 隔离性:一个会话和另一个会话之间是互相隔离的
- 持久性:执行了就执行了,数据保存在硬盘上
典型例子:银行转账,A给B转账100万,首先要A的账户减去100万,然后B的账户增加100万,如果中间断了那就出问题了。所以我们人为的将这件事进行原子化,做成一个最小单位。要么一起成功要么一起失败。
redis是一种简单的数据存储形式,redis的事务是不支持回滚的。
之前的sqlserver的事务,开了一个事务,去修改表的数据。然后有一个新的会话,或者新的连接,这个时候如果我们这儿连接去修改或者查询这个表时,可能会一直等待,直到事务操作完毕。
而redis则不然,如果同样的操作使用redis事务的话,会导致事务操作失败。redis在开启事务前监听了3个要修改key的版本号,如果在这个事务期间,其他的连接可以修改这3个key对应的值,但是会影响当前开启事务这个会话的操作,让事务提交不成功。
//事务模式
using (RedisClient client = new RedisClient("127.0.0.1", 6379, "12345", 10))
{
//删除当前数据库中的所有Key 默认删除的是db0
client.FlushDb();
//删除所有数据库中的key
//client.FlushAll();
client.Set("a", "1");
client.Set("b", "1");
client.Set("c", "1");
//获取当前这三个key的版本号 实现事务
client.Watch("a", "b", "c");
using (var trans = client.CreateTransaction())
{
trans.QueueCommand(p => p.Set("a", "3"));
trans.QueueCommand(p => p.Set("b", "3"));
trans.QueueCommand(p => p.Set("c", "3"));
//提交事务 如果在触发事务过程中,其他进程操作了当前的key,则事务提交失败,就是没有指令没有修改成功
var flag = trans.Commit();
// ID KEY
Console.WriteLine(flag);
}
//根据key取出值,返回string
Console.WriteLine(client.Get<string>("a") + ":" + client.Get<string>
("b") + ":" + client.Get<string>
("c"));
Console.ReadLine();
}
所以,在redis使用事务的情况下,必须使用watch进行监听一下对应的key值,凡是需要事务操作的key,都要包含在watch里面进行监听。
单线程理解误区:(看代码)
//单线程理解误区
using (RedisClient client1 = new RedisClient("127.0.0.1", 6379, "12345", 10))
{
//删除当前数据库中的所有Key 默认删除的是db0
client1.FlushDb();
//删除所有数据库中的key
//client.FlushAll();
client1.Del("number");
for (int i = 0; i < 10; i++)
{
Task.Run(() =>
{
using (RedisClient client = new RedisClient("127.0.0.1", 6379, "12345", 10))
{
if (client.Get("number") == null)
{
Console.WriteLine("number == null");
client.Set<string>("number", "100");
}
else
{
Console.WriteLine("number != null");
}
}
});
}
}
Console.ReadLine();
在我的电脑上最终打印结果:
number == null
number == null
number == null
number == null
number != null
number != null
number != null
number != null
number != null
number != null
这里面的语句(if (client.Get("number") == null))会出现4次执行成功,这会误导我们对单线程的理解。说明进入这个判断时,有4个同时进入了,这4个获取过程会排队到redis里面,redis会一个个的进行执行,那么这4个就都是成功的,所以会有4次成功执行,而这4次执行完之后,key就被赋值了,其他线程进入时,就会不为null。这里面的单线程指的是redis执行的过程,而不是程序中线程执行的过程。如果想要只进入一次,就需要对这个过程加锁。(我的理解是,因为我的CPU是2核4线程,所以会有4个线程同时进入)
//单线程理解误区
using (RedisClient client1 = new RedisClient("127.0.0.1", 6379, "12345", 10))
{
//删除当前数据库中的所有Key 默认删除的是db0
client1.FlushDb();
//删除所有数据库中的key
//client.FlushAll();
client1.Del("number");
for (int i = 0; i < 10; i++)
{
Task.Run(() =>
{
using (RedisClient client = new RedisClient("127.0.0.1", 6379, "12345", 10))
{
lock ("123")
{
if (client.Get("number") == null)
{
Console.WriteLine("number == null");
client.Set<string>("number", "100");
}
else
{
Console.WriteLine("number != null");
}
}
}
});
}
}
Console.ReadLine();
Redis之品鉴之旅(五)的更多相关文章
- Redis之品鉴之旅(一)
Redis之品鉴之旅(一) 好知识就如好酒,需要我们坐下来,静静的慢慢的去品鉴.Redis作为主流nosql数据库,在提升性能的方面是不可或缺的.下面就拿好小板凳,我们慢慢的来一一品鉴. 1)redi ...
- Redis之品鉴之旅(七)
分布式锁 1)阻塞锁: 尝试在redis中创建一个字符串结构缓存,方法传入的key,value为锁的过期时间timeout的时间戳. 若redis中没有这个key,则创建成功(即抢到锁),然后立即返回 ...
- Redis之品鉴之旅(六)
持久化 快照的方式(RDB) 文件追加方式(AOF) 快照形式: save和bgsave能快速的备份数据.但是.........., Save命令:将内存数据镜像保存为rdb文件,由于redis是单线 ...
- Redis之品鉴之旅(二)
2)hash类型,上代码 using (RedisClient client = new RedisClient("127.0.0.1", 6379, "12345&qu ...
- Redis之品鉴之旅(四)
发布订阅,简单场景下的发布订阅完全可以使用. 可以简单的理解,将一个公众号视为发布者,关注公众号的人视作订阅者,公众号发布一条文章或者消息,凡事订阅公众号的都可以收到消息.一个人可以订阅多个公众号,一 ...
- Redis之品鉴之旅(三)
3)Set,可以去重的.无序的集合.可以取交集.并集.zset(sorted set),有序的.去重的集合,排序不是根据value排序,而是根据score排序. using (RedisClient ...
- redis成长之路——(五)
单例.哨兵.Cluster redis应用广泛,主要体现于实际场景的可用化,但是对于码农来说初步入手很多理念难以理解:码农的想法就是:为什么我要管那么多,我只想用,能用就行!所以必须将三个场景透明化. ...
- Redis源码阅读(五)集群-故障迁移(上)
Redis源码阅读(五)集群-故障迁移(上) 故障迁移是集群非常重要的功能:直白的说就是在集群中部分节点失效时,能将失效节点负责的键值对迁移到其他节点上,从而保证整个集群系统在部分节点失效后没有丢失数 ...
- Redis数据结构详解,五种数据结构分分钟掌握
redis数据类型分为:字符串类型.散列类型.列表类型.集合类型.有序集合类型.redis这么火,它运行有多块?一台普通的笔记本电脑,可以在1秒钟内完成十万次的读写操作.原子操作:最小的操作单位,不能 ...
随机推荐
- 配置之XML--读取XML文件 转存为Key-Value
将XML文件读取 绑定数据至Dictionary Eg: Xml文件 <?xml version="1.0" encoding="utf-8" ?> ...
- 使用VSCode创建第一个VUE项目
vue init webpack vue_test回车,然后输入工程名称vue_test vue:Missing space before value for key 'components' 原因是 ...
- WPF 饼状图,柱形图,折线图 (2 折线图)
折线图在柱形图的基础上,做了一些修改.大概效果和用法如下. X轴和Y轴的刻度,使用用了Path的Figures属性,绘制多条Figure+LineSegment完成. 同时,由于折线图很可能会画多条线 ...
- Linux中Java开发常用的软件总结:
开发工具下载: Tomcat下载:wget http://learning.happymmall.com/tomcat/apache-tomcat-7.0.73.tar.gzJDK下载: wget h ...
- Ansible部署及配置介绍
原文转自:https://www.cnblogs.com/itzgr/p/10233932.html作者:木二 目录 一 Ansible的安装部署 1.1 PIP方式 1.2 YUM方式 二 Ansi ...
- 博观约取系列 ~ 探测Bert Finetune对向量空间的影响
熟悉NLP的同学对Bert Finetune一定不陌生,基本啥任务上来都可以Bert Finetune试一把.可是模型微调一定比直接使用预训练模型效果好么?微调究竟对Bert的向量空间产生了哪些影响嘞 ...
- LVS实现(VS/DR)负载均衡和Keepalived高可用
LVS是Linux Virtual Server的简写即Linux虚拟服务器,是一个虚拟的服务器集群系统一组服务器通过高速的局域网或者地理分布的广域网相互连接,在它们的前端有一个负载调度器(Load ...
- vue 微信二维码扫码登录,附加 自定义样式
大概流程: 先安装 微信 的登录, 然后 局部引入,局部注册,方法调用,存 token,跳转路由 npm 安装 npm install vue-wxlogin --save-dev 微信安装 微信 ...
- 洛谷P2424 约数和 题解
题目 约数和 题解 此题可以说完全就是一道数学题,不难看出这道题所求的是 \(\sum\limits_{i=x}^{y}{\sum\limits_{d|i}{d}}\) 的值. 很显然,用暴力枚举肯定 ...
- Mysql 面试宝典
实时更新 你用过哪些数据库? mysql redis mysql 和 redis 的区别? 比较点 Mysql Redis 数据库类型 关系型 非关系型 作用 持久化层 存储需要持久化的数据,数据存在 ...