EF+Redis(StackExchange.Redis)实现分布式锁,自测可行
电商平台 都会有抢购的情况,比如 1元抢购。 而抢购 最重要的 就是库存,很多情况下 库存处理不好,就会出现超卖现象。
本文将用redis为缓存,StackExchange 框架,消息队列方式 实现分布式锁的情况
一,效果
先看效果,

窗体下单 构建高并发情况

开多个控制台应用程序 处理订单
二,配置Redis
<Redis.Service>
<DbConfig Name="Order_DBName" Hosts="127.0.0.1:6379" dbNum=""> </DbConfig>
<DbConfig Name="Product_DbName" Hosts="127.0.0.1:6379" dbNum=""> </DbConfig>
模拟用户下单
private void button1_Click(object sender, EventArgs e)
{
var orderCount = Convert.ToInt32(txt_OrderCount.Text);
var productId = Convert.ToInt32(txt_ProductId.Text); var productCount = Convert.ToInt32(txt_ProductCount.Text); for (int i = ; i < orderCount; i++)
{
RedisOrderModel cacheOrder = new RedisOrderModel()
{
Count = productCount,
OrderNo = (orderNo += ).ToString(),
ProductId = productId
};
orderRedis.Push(cacheOrder);
} }
控制台程序 处理订单
public void QueueList()
{
RedisOrderMessage redis = new RedisOrderMessage();
while (true)
{
try
{
var cacheOrder = redis.Pop();
if (cacheOrder == null)
{
Console.WriteLine("无订单,休息100毫秒");
Thread.Sleep();
continue;
} while (ThreadCount<=)
{
Console.WriteLine("线程已满,休息100毫秒");
Thread.Sleep();
}
//ThreadCount--;
Thread thread = new Thread(new ThreadStart(cacheOrder.CreateOrder));
thread.Start();
Console.WriteLine("正在处理订单,休息100毫秒");
Thread.Sleep();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message + "," + ex.StackTrace);
Thread.Sleep();
}
finally
{
ThreadCount++;
} }
}
使用分布式锁,判断库存是否足够
public void LockStore(string productId, int count)
{
var keyInfo = AddSysCustomKey(productId); if (!Exists(keyInfo))
{
throw new Exception("商品缓存缓存不存在");
}
var redisConfig = ReadRedisConfig.GetRedisConfig(DB_Name);
var lockdb = redisConfig.GetDatabase(-);
var db = redisConfig.GetDatabase();
var token = Environment.MachineName;
while (true)
{
//db.LockRelease(keyInfo, token);
var con = lockdb.LockTake(keyInfo, token, TimeSpan.FromSeconds(10.0), CommandFlags.None);
//var con = db.LockTake(keyInfo, token, TimeSpan.FromSeconds(20), CommandFlags.None);
if (con)
{
try
{
var product = ConvertObj<CacheProduct>(db.StringGet(keyInfo));
if (product.Count < count)
{
throw new Exception("数量不够,下单失败");
}
product.Count -= count;
var json = ConvertJson(product);
db.StringSet(keyInfo, json); }
finally
{
lockdb.LockRelease(keyInfo, token); }
break;
}
} }
源码地址:
https://github.com/buruainiaaaa/CacheDemo.git
EF+Redis(StackExchange.Redis)实现分布式锁,自测可行的更多相关文章
- 使用Redis SETNX 命令实现分布式锁
基于setnx和getset http://blog.csdn.net/lihao21/article/details/49104695 使用Redis的 SETNX 命令可以实现分布式锁,下文介绍其 ...
- Redis 上实现的分布式锁
转载Redis 上实现的分布式锁 由于近排很忙,忙各种事情,还有工作上的项目,已经超过一个月没写博客了,确实有点惭愧啊,没能每天或者至少每周坚持写一篇博客.这一个月里面接触到很多新知识,同时也遇到很多 ...
- 在 Redis 上实现的分布式锁
由于近排很忙,忙各种事情,还有工作上的项目,已经超过一个月没写博客了,确实有点惭愧啊,没能每天或者至少每周坚持写一篇博客.这一个月里面接触到很多新知识,同时也遇到很多技术上的难点,在这我将对每一个有用 ...
- Redis整合Spring实现分布式锁
spring把专门的数据操作独立封装在spring-data系列中,spring-data-redis是对Redis的封装 <dependencies> <!-- 添加spring- ...
- 使用Redis SETNX 命令实现分布式锁(转载)
使用Redis的 SETNX 命令可以实现分布式锁,下文介绍其实现方法. SETNX命令简介 命令格式 SETNX key value 将 key 的值设为 value,当且仅当 key 不存在. 若 ...
- 【连载】redis库存操作,分布式锁的四种实现方式[一]--基于zookeeper实现分布式锁
一.背景 在电商系统中,库存的概念一定是有的,例如配一些商品的库存,做商品秒杀活动等,而由于库存操作频繁且要求原子性操作,所以绝大多数电商系统都用Redis来实现库存的加减,最近公司项目做架构升级,以 ...
- 基于 Redis 实现简单的分布式锁
摘要 分布式锁在很多应用场景下是非常有效的手段,比如当运行在多个机器上的不同进程需要访问同一个竞争资源的时候,那么就会涉及到进程对资源的加锁和释放,这样才能保证数据的安全访问.分布式锁实现的方案有很多 ...
- 基于Redis实现简单的分布式锁【理论】
摘要 分布式锁在很多应用场景下是非常有效的手段,比如当运行在多个机器上的不同进程需要访问同一个竞争资源的时候,那么就会涉及到进程对资源的加锁和释放,这样才能保证数据的安全访问.分布式锁实现的方案有很多 ...
- Redis、Zookeeper实现分布式锁——原理与实践
Redis与分布式锁的问题已经是老生常谈了,本文尝试总结一些Redis.Zookeeper实现分布式锁的常用方案,并提供一些比较好的实践思路(基于Java).不足之处,欢迎探讨. Redis分布式锁 ...
随机推荐
- css渲染(一) 字体和文本
一.字体属性 1.默认字体系列 chrome/opera:"宋体" firefox:"微软雅黑" safari/IE:Times,"宋体" ...
- iOS应用如何得知用户有新拍的图片?
首先,应用要知道图片库中的新图片,最重要是要有图片库的访问权限.然后每张图片除了图片本身的构成要素(像素)外,还会保存图片的拍摄时间(时间戳),地点等相关信息.时间戳就是判断新拍照片的最主要依据.
- onclick与this
这个其实也是一个很基础的问题,不过又碰巧遇到了,所以记录一下. 假设我们有这么一个需求,按下按钮,弹出提示框,显示按钮的value值. 可能有一些人提起笔就写: <button onclick= ...
- POJ - 3268 单源最短路
题意:给定一些有向边,以及一个目的地,从某个点到达目的地,再从目的地回到那个点.共有n个点,问这n个点花费最大是多少? 思路:从目的地回去直接把目的地作为源点即可.那么从某个点到达目的地应该如何得到最 ...
- Oracle 11g数据库安装和卸载教程
Oracle11g的安装教程 同时解压缩两个zip文件,生成一个database文件夹,进入到database文件夹,点击setup 去掉安全更新的选项,直接下一步 选择创建和配置数据库,点击下一步 ...
- Redis实现数据库读写分离
Redis简介 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.从2010年3月15日起,Redis的开发工作 ...
- Linux基础二
linux命令分类 内部命令:属于shell解释器 外部命令:独立于shell解释器 检查命令类型 type:检查命令字的类型 [root@localhost ~]# type ls ls 是 `ls ...
- 一文解决python模块导入
python 模块导入 原理 查找是按照 sys.path 中的路径挨个扫描.若都不存在则提示error. sys.path路径第一个是当前运行脚本所在的目录,其后是PYTHONPATH(一般若步专门 ...
- 【linux】安装mysql出现 no curses错误解决方法
安装mysql,在./configure时出现错误:error: No curses/termcap library found的解决办法 mysql版本:5.1.30 已经不记得这次是第几次安装my ...
- Java中的a++和++a的区别
1.a++和++a的区别 a++表示先将a放在表达式中运算,然后再加1: ++a表示先将a加1,然后再放在表达式中运算 2.实例 (1)Java代码 /** * @Title:JiaJia.java ...