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分布式锁 ...
随机推荐
- Linux下 开启防火墙端口
命令行输入: vi /etc/sysconfig/iptables 将 -A INPUT -m state --state NEW -m tcp -p tcp --dport 端口号 -j ACCEP ...
- OSI网络模型
OSI中的层 功能 TCP/IP协议族 应用层 文件传输,电子邮件,文件服务,虚拟终端 TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet 表示层 数 ...
- linux 版本控制及rpm打包
版本控制 subversion:是一个自由/开源的版本控制系统,在subversion管理下,文件和目录可以超越时空subversion允许你数据恢复到早期版本,或者是检查数据修改历史许多人将版本控制 ...
- Linux基础一
基本命令 useradd xxx 创建一个用户 uname 查看系统架构信息 uname -a 显示详细信息 uname -r 显示内核信息 date 显示当前网络时间 cat ...
- 【前端】JavaScript中prototype和__proto__的区别
转载请注明出处:http://www.cnblogs.com/shamoyuu/p/prototype.html 经常有小伙伴问我关于prototype和__proto__的问题,觉得有必要写一篇博客 ...
- FFMPEG在windows平台编译的详细过程,包括环境安装
下面开始: 由于FFMpeg是基于Linux开发的开源项目,源代码和Windows下最常见的Visual Studio提供的C/C++编译器不兼容,因此它不能使用MSVC++编译.要想使用FFMpeg ...
- ffmpeg tutorial01 再分析
如下图
- javascript 获取滚动条距离顶部的位置(兼容所有的)。
function getScrollTop() { var scrollPos; if (window.pageYOffset) { scrollPos = window.pageYOffset; } ...
- 【dedecms】DEDE列表页调用文章内容第一张图片(非缩略图)方法
打开 ../ include/ common.func.php 添加代码 //将缩放图转变为文章第一张图片 function firstimg($str_pic) { $str_sub=substr( ...
- JavaScript获取屏幕和页面的宽度和高度
JavaScript获取屏幕和页面的宽度和高度 1.设计源码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN ...