第五节:拉模式的消费者优化(数量块和时间块)
一. 前言
1.背景
最初版本的消费者一条一条获取,然后创建订单扣减库存,非常慢,我们希望在保证消费顺序的情况下提升消费速度。
2.设计思路
A.我们设置两个维度:数量 和 时间,比如当从队列中获取的数量达到200条的时候提交 或者 2s提交一次(但必须有数据)
B.EFCore默认提交大数据量可能比较慢, 我们可以直接调用SQL语句处理 或者 用 EFCore.BulkExtensions组件处理(推荐,大约4w条数据的新增在1.2秒处理完)
C.扩展测试一下Dapper和ADO.Net相比B中的方案是否有明显的优势
关于执行速度问题,可参考:
https://www.cnblogs.com/yaopengfei/p/12205117.html
3.分析
A. EF上下文放在最外层,查询的时候使用的含状态追踪的语句,在程序不停止的时候,手动去修改了库存,这里的程序不会更新成最新的库存,存在缓存问题。
解决方案:加上AsNoTracking 而且savechange后要释放一下. db.Entry<T_SeckillArticle>(sArctile).State = EntityState.Detached;
B.EF上下文放在最外层,内部while(true),这个上下文就会一直不释放,总有一刻会报错, 如何解决?
解决方案:放到内部,每次执行业务的时候都using一下,而且这种方案就不存在缓存问题了,不需要单独解决A的缓存问题,因为每次上下文都是一个新的。
二. 代码实操
1. 最初版本
代码分享:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#region 01-EFCore原始版--存在缓存问题,库存计算错误 //{ // Console.WriteLine("下面开始执行消费业务"); // using (ESHOPContext db = new ESHOPContext()) // { // RedisHelp redisHelp = new RedisHelp("localhost:6379"); // var redisDB = redisHelp.GetDatabase(); // while (true) // { // try // { // var data = (string)redisDB.ListRightPop("200001"); // if (!string.IsNullOrEmpty(data)) // { // List<string> tempData = data.Split('-').ToList(); // { // //1.扣减库存 // var sArctile = db.Set<T_SeckillArticle>().Where(u => u.id == "300001").FirstOrDefault(); // sArctile.articleStockNum = sArctile.articleStockNum - 1; // //2. 插入订单信息 // T_Order tOrder = new T_Order(); // tOrder.id = Guid.NewGuid().ToString("N"); // tOrder.userId = tempData[0]; // tOrder.orderNum = tempData[3]; // tOrder.articleId = tempData[1]; // tOrder.orderTotalPrice = Convert.ToDecimal(tempData[2]); // tOrder.addTime = DateTime.Now; // tOrder.orderStatus = 0; // db.Add<T_Order>(tOrder); // int count = db.SaveChanges(); // Console.WriteLine($"执行成功,条数为:{count},当前库存为:{ sArctile.articleStockNum}"); // } // } // else // { // Console.WriteLine("暂时没有订单信息,休息一下"); // Thread.Sleep(1000); // } // } // catch (Exception ex) // { // Console.WriteLine($"执行失败-{ex.Message}"); // } // } // } //} #endregion #region 02-EFCore改造版-分批处理(数量和时间)--存在缓存问题,库存计算错误 //{ // Console.WriteLine("下面开始执行消费业务"); // using (ESHOPContext db = new ESHOPContext()) // { // RedisHelp redisHelp = new RedisHelp("localhost:6379"); // var redisDB = redisHelp.GetDatabase(); // //临时存储从队列中取出来的信息 // List<string> orderInforList = new List<string>(); // Stopwatch watch = new Stopwatch(); // watch.Start(); // while (true) // { // try // { // var data = (string)redisDB.ListRightPop("200001"); // Console.WriteLine(data); // if (!string.IsNullOrEmpty(data)) // { // orderInforList.Add(data); // } // else // { // Console.WriteLine("暂时没有订单信息,休息一下"); // Thread.Sleep(2000); // } // if (orderInforList.Count() >= 100 || watch.ElapsedMilliseconds > 2000) // { // if (orderInforList.Count() > 0) // { // //1.扣减库存 // var sArctile = db.Set<T_SeckillArticle>().Where(u => u.id == "300001").FirstOrDefault(); // sArctile.articleStockNum = sArctile.articleStockNum - orderInforList.Count(); // //2. 插入订单信息 // foreach (var item in orderInforList) // { // List<string> tempData = item.Split('-').ToList(); // T_Order tOrder = new T_Order(); // tOrder.id = Guid.NewGuid().ToString("N"); // tOrder.userId = tempData[0]; // tOrder.orderNum = tempData[3]; // tOrder.articleId = tempData[1]; // tOrder.orderTotalPrice = Convert.ToDecimal(tempData[2]); // tOrder.addTime = DateTime.Now; // tOrder.orderStatus = 0; // db.Add<T_Order>(tOrder); // } // int count = db.SaveChanges(); // Console.WriteLine($"执行成功,条数为:{count}"); // } // else // { // Thread.Sleep(1000); // Console.WriteLine("接着休息"); // } // //统一:清空orderInforList的临时数据 和 重置时间 // orderInforList.Clear(); // watch.Reset(); // watch.Start(); // } // } // catch (Exception ex) // { // Console.WriteLine($"执行失败:{ex.Message}"); // } // } // } //} #endregion #region 03-EFCore调用SQL--没有缓存问题 //{ // Console.WriteLine("下面开始执行消费业务"); // using (ESHOPContext db = new ESHOPContext()) // { // RedisHelp redisHelp = new RedisHelp("localhost:6379"); // var redisDB = redisHelp.GetDatabase(); // //临时存储从队列中取出来的信息 // List<string> orderInforList = new List<string>(); // Stopwatch watch = new Stopwatch(); // watch.Start(); // while (true) // { // try // { // var data = (string)redisDB.ListRightPop("200001"); // Console.WriteLine(data); // if (!string.IsNullOrEmpty(data)) // { // orderInforList.Add(data); // } // else // { // Console.WriteLine("暂时没有订单信息,休息一下"); // Thread.Sleep(2000); // } // if (orderInforList.Count() >= 100 || watch.ElapsedMilliseconds > 2000) // { // if (orderInforList.Count() > 0) // { // using (var transaction = db.Database.BeginTransaction()) // { // try // { // //1.扣减库存 // string sql1 = $"update T_SeckillArticle set articleStockNum=articleStockNum-{orderInforList.Count()} where id='300001';"; // db.Database.ExecuteSqlRaw(sql1); // //2. 插入订单信息 // string sql2 = ""; // foreach (var item in orderInforList) // { // List<string> tempData = item.Split('-').ToList(); // sql2 = sql2 + @$"insert into T_Order(id,userId,orderNum,articleId,orderTotalPrice,addTime,orderStatus) values" + // $"('{ Guid.NewGuid().ToString("N")}','{tempData[0]}','{tempData[3]}',{tempData[1]},'{ Convert.ToDecimal(tempData[2])}','{DateTime.Now}',0);"; // } // db.Database.ExecuteSqlRaw(sql2); // transaction.Commit(); // Console.WriteLine("提交成功"); // } // catch (Exception ex) // { // //using包裹事务,失败了会自动回滚 // Console.WriteLine($"提交失败:{ex.Message}"); // } // } // } // else // { // Thread.Sleep(1000); // Console.WriteLine("接着休息"); // } // //统一:清空orderInforList的临时数据 和 重置时间 // orderInforList.Clear(); // watch.Reset(); // watch.Start(); // } // } // catch (Exception ex) // { // Console.WriteLine($"执行失败:{ex.Message}"); // } // } // } //} #endregion #region 04-基于EFCore.BulkExtensions优化--没有缓存问题 //{ // Console.WriteLine("下面开始执行消费业务"); // using (ESHOPContext db = new ESHOPContext()) // { // RedisHelp redisHelp = new RedisHelp("localhost:6379"); // var redisDB = redisHelp.GetDatabase(); // //临时存储从队列中取出来的信息 // List<string> orderInforList = new List<string>(); // Stopwatch watch = new Stopwatch(); // watch.Start(); // while (true) // { // try // { // var data = (string)redisDB.ListRightPop("200001"); // Console.WriteLine(data); // if (!string.IsNullOrEmpty(data)) // { // orderInforList.Add(data); // } // else // { // Console.WriteLine("暂时没有订单信息,休息一下"); // Thread.Sleep(1000); // } // if (orderInforList.Count() >= 100 || watch.ElapsedMilliseconds > 2000) // { // if (orderInforList.Count() > 0) // { // //执行消费业务 // using (var transaction = db.Database.BeginTransaction()) // { // try // { // //1.扣减库存 // db.Set<T_SeckillArticle>().Where(u => u.id == "300001").BatchUpdate(a => new T_SeckillArticle { articleStockNum = a.articleStockNum - orderInforList.Count() }); // //2. 插入订单信息 // List<T_Order> insertOrderList = new List<T_Order>(); // foreach (var item in orderInforList) // { // List<string> tempData = item.Split('-').ToList(); // T_Order tOrder = new T_Order(); // tOrder.id = Guid.NewGuid().ToString("N"); // tOrder.userId = tempData[0]; // tOrder.orderNum = tempData[3]; // tOrder.articleId = tempData[1]; // tOrder.orderTotalPrice = Convert.ToDecimal(tempData[2]); // tOrder.addTime = DateTime.Now; // tOrder.orderStatus = 0; // insertOrderList.Add(tOrder); // } // db.BulkInsert(insertOrderList); // //统一提交事务 // transaction.Commit(); // Console.WriteLine($"消费成功。。。。"); // } // catch (Exception ex) // { // Console.WriteLine($"消费失败:{ex.Message}"); // } // } // } // else // { // Thread.Sleep(1000); // Console.WriteLine("接着休息"); // } // //统一:清空orderInforList的临时数据 和 重置时间 // orderInforList.Clear(); // watch.Reset(); // watch.Start(); // } // } // catch (Exception ex) // { // Console.WriteLine($"执行失败:{ex.Message}"); // } // } // } //} #endregion
2. 缓存问题导致库存扣减错误的bug
代码分享:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/********************************************下面是解决--缓存问题导致库存扣减错误的bug************************************************************/ #region 01-EFCore原始版 //{ // Console.WriteLine("下面开始执行消费业务"); // using (ESHOPContext db = new ESHOPContext()) // { // RedisHelp redisHelp = new RedisHelp("localhost:6379"); // var redisDB = redisHelp.GetDatabase(); // while (true) // { // try // { // var data = (string)redisDB.ListRightPop("200001"); // if (!string.IsNullOrEmpty(data)) // { // List<string> tempData = data.Split('-').ToList(); // { // //1.扣减库存 --去掉状态追踪 // var sArctile = db.Set<T_SeckillArticle>().AsNoTracking().Where(u => u.id == "300001").FirstOrDefault(); // sArctile.articleStockNum = sArctile.articleStockNum - 1; // db.Update(sArctile); // //2. 插入订单信息 // T_Order tOrder = new T_Order(); // tOrder.id = Guid.NewGuid().ToString("N"); // tOrder.userId = tempData[0]; // tOrder.orderNum = tempData[3]; // tOrder.articleId = tempData[1]; // tOrder.orderTotalPrice = Convert.ToDecimal(tempData[2]); // tOrder.addTime = DateTime.Now; // tOrder.orderStatus = 0; // db.Add<T_Order>(tOrder); // int count = db.SaveChanges(); // //释放一下--否则报错 // db.Entry<T_SeckillArticle>(sArctile).State = EntityState.Detached; // Console.WriteLine($"执行成功,条数为:{count},当前库存为:{ sArctile.articleStockNum}"); // } // } // else // { // Console.WriteLine("暂时没有订单信息,休息一下"); // Thread.Sleep(1000); // } // } // catch (Exception ex) // { // Console.WriteLine($"执行失败-{ex.Message}"); // } // } // } //} #endregion #region 02-EFCore改造版-分批处理(数量和时间) //{ // Console.WriteLine("下面开始执行消费业务"); // using (ESHOPContext db = new ESHOPContext()) // { // RedisHelp redisHelp = new RedisHelp("localhost:6379"); // var redisDB = redisHelp.GetDatabase(); // //临时存储从队列中取出来的信息 // List<string> orderInforList = new List<string>(); // Stopwatch watch = new Stopwatch(); // watch.Start(); // while (true) // { // try // { // var data = (string)redisDB.ListRightPop("200001"); // Console.WriteLine(data); // if (!string.IsNullOrEmpty(data)) // { // orderInforList.Add(data); // } // else // { // Console.WriteLine("暂时没有订单信息,休息一下"); // Thread.Sleep(2000); // } // if (orderInforList.Count() >= 100 || watch.ElapsedMilliseconds > 2000) // { // if (orderInforList.Count() > 0) // { // //1.扣减库存--去掉状态追踪 // var sArctile = db.Set<T_SeckillArticle>().AsNoTracking().Where(u => u.id == "300001").FirstOrDefault(); // sArctile.articleStockNum = sArctile.articleStockNum - orderInforList.Count(); // db.Update(sArctile); // //2. 插入订单信息 // foreach (var item in orderInforList) // { // List<string> tempData = item.Split('-').ToList(); // T_Order tOrder = new T_Order(); // tOrder.id = Guid.NewGuid().ToString("N"); // tOrder.userId = tempData[0]; // tOrder.orderNum = tempData[3]; // tOrder.articleId = tempData[1]; // tOrder.orderTotalPrice = Convert.ToDecimal(tempData[2]); // tOrder.addTime = DateTime.Now; // tOrder.orderStatus = 0; // db.Add<T_Order>(tOrder); // } // int count = db.SaveChanges(); // //释放一下--否则报错 // db.Entry<T_SeckillArticle>(sArctile).State = EntityState.Detached; // Console.WriteLine($"执行成功,条数为:{count}"); // } // else // { // Thread.Sleep(1000); // Console.WriteLine("接着休息"); // } // //统一:清空orderInforList的临时数据 和 重置时间 // orderInforList.Clear(); // watch.Reset(); // watch.Start(); // } // } // catch (Exception ex) // { // Console.WriteLine($"执行失败:{ex.Message}"); // } // } // } //} #endregion #region 03-EFCore调用SQL--不变 //{ // Console.WriteLine("下面开始执行消费业务"); // using (ESHOPContext db = new ESHOPContext()) // { // RedisHelp redisHelp = new RedisHelp("localhost:6379"); // var redisDB = redisHelp.GetDatabase(); // //临时存储从队列中取出来的信息 // List<string> orderInforList = new List<string>(); // Stopwatch watch = new Stopwatch(); // watch.Start(); // while (true) // { // try // { // var data = (string)redisDB.ListRightPop("200001"); // Console.WriteLine(data); // if (!string.IsNullOrEmpty(data)) // { // orderInforList.Add(data); // } // else // { // Console.WriteLine("暂时没有订单信息,休息一下"); // Thread.Sleep(2000); // } // if (orderInforList.Count() >= 100 || watch.ElapsedMilliseconds > 2000) // { // if (orderInforList.Count() > 0) // { // using (var transaction = db.Database.BeginTransaction()) // { // try // { // //1.扣减库存 // string sql1 = $"update T_SeckillArticle set articleStockNum=articleStockNum-{orderInforList.Count()} where id='300001';"; // db.Database.ExecuteSqlRaw(sql1); // //2. 插入订单信息 // string sql2 = ""; // foreach (var item in orderInforList) // { // List<string> tempData = item.Split('-').ToList(); // sql2 = sql2 + @$"insert into T_Order(id,userId,orderNum,articleId,orderTotalPrice,addTime,orderStatus) values" + // $"('{ Guid.NewGuid().ToString("N")}','{tempData[0]}','{tempData[3]}',{tempData[1]},'{ Convert.ToDecimal(tempData[2])}','{DateTime.Now}',0);"; // } // db.Database.ExecuteSqlRaw(sql2); // transaction.Commit(); // Console.WriteLine("提交成功"); // } // catch (Exception ex) // { // //using包裹事务,失败了会自动回滚 // Console.WriteLine($"提交失败:{ex.Message}"); // } // } // } // else // { // Thread.Sleep(1000); // Console.WriteLine("接着休息"); // } // //统一:清空orderInforList的临时数据 和 重置时间 // orderInforList.Clear(); // watch.Reset(); // watch.Start(); // } // } // catch (Exception ex) // { // Console.WriteLine($"执行失败:{ex.Message}"); // } // } // } //} #endregion #region 04-基于EFCore.BulkExtensions优化--不变 //{ // Console.WriteLine("下面开始执行消费业务"); // using (ESHOPContext db = new ESHOPContext()) // { // RedisHelp redisHelp = new RedisHelp("localhost:6379"); // var redisDB = redisHelp.GetDatabase(); // //临时存储从队列中取出来的信息 // List<string> orderInforList = new List<string>(); // Stopwatch watch = new Stopwatch(); // watch.Start(); // while (true) // { // try // { // var data = (string)redisDB.ListRightPop("200001"); // Console.WriteLine(data); // if (!string.IsNullOrEmpty(data)) // { // orderInforList.Add(data); // } // else // { // Console.WriteLine("暂时没有订单信息,休息一下"); // Thread.Sleep(1000); // } // if (orderInforList.Count() >= 100 || watch.ElapsedMilliseconds > 2000) // { // if (orderInforList.Count() > 0) // { // //执行消费业务 // using (var transaction = db.Database.BeginTransaction()) // { // try // { // //1.扣减库存 // db.Set<T_SeckillArticle>().Where(u => u.id == "300001").BatchUpdate(a => new T_SeckillArticle { articleStockNum = a.articleStockNum - orderInforList.Count() }); // //2. 插入订单信息 // List<T_Order> insertOrderList = new List<T_Order>(); // foreach (var item in orderInforList) // { // List<string> tempData = item.Split('-').ToList(); // T_Order tOrder = new T_Order(); // tOrder.id = Guid.NewGuid().ToString("N"); // tOrder.userId = tempData[0]; // tOrder.orderNum = tempData[3]; // tOrder.articleId = tempData[1]; // tOrder.orderTotalPrice = Convert.ToDecimal(tempData[2]); // tOrder.addTime = DateTime.Now; // tOrder.orderStatus = 0; // insertOrderList.Add(tOrder); // } // db.BulkInsert(insertOrderList); // //统一提交事务 // transaction.Commit(); // Console.WriteLine($"消费成功。。。。"); // } // catch (Exception ex) // { // Console.WriteLine($"消费失败:{ex.Message}"); // } // } // } // else // { // Thread.Sleep(1000); // Console.WriteLine("接着休息"); // } // //统一:清空orderInforList的临时数据 和 重置时间 // orderInforList.Clear(); // watch.Reset(); // watch.Start(); // } // } // catch (Exception ex) // { // Console.WriteLine($"执行失败:{ex.Message}"); // } // } // } //} #endregion
3. 调整EF上下文位置,防止长时间链接EF上下文销毁(最终版)
代码分享:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/*******************************************调整EF上下文位置,防止长时间链接EF上下文销毁(最终版)************************************************************/ #region 01-EFCore原始版 //{ // Console.WriteLine("下面开始执行消费业务"); // RedisHelp redisHelp = new RedisHelp("localhost:6379"); // var redisDB = redisHelp.GetDatabase(); // while (true) // { // try // { // var data = (string)redisDB.ListRightPop("200001"); // if (!string.IsNullOrEmpty(data)) // { // List<string> tempData = data.Split('-').ToList(); // using (ESHOPContext db = new ESHOPContext()) // { // //1.扣减库存 // var sArctile = db.Set<T_SeckillArticle>().Where(u => u.id == "300001").FirstOrDefault(); // sArctile.articleStockNum = sArctile.articleStockNum - 1; // //2. 插入订单信息 // T_Order tOrder = new T_Order(); // tOrder.id = Guid.NewGuid().ToString("N"); // tOrder.userId = tempData[0]; // tOrder.orderNum = tempData[3]; // tOrder.articleId = tempData[1]; // tOrder.orderTotalPrice = Convert.ToDecimal(tempData[2]); // tOrder.addTime = DateTime.Now; // tOrder.orderStatus = 0; // db.Add<T_Order>(tOrder); // int count = db.SaveChanges(); // Console.WriteLine($"执行成功,条数为:{count},当前库存为:{ sArctile.articleStockNum}"); // } // } // else // { // Console.WriteLine("暂时没有订单信息,休息一下"); // Thread.Sleep(1000); // } // } // catch (Exception ex) // { // Console.WriteLine($"执行失败-{ex.Message}"); // } // } //} #endregion #region 02-EFCore改造版-分批处理(数量和时间) //{ // Console.WriteLine("下面开始执行消费业务"); // RedisHelp redisHelp = new RedisHelp("localhost:6379"); // var redisDB = redisHelp.GetDatabase(); // //临时存储从队列中取出来的信息 // List<string> orderInforList = new List<string>(); // Stopwatch watch = new Stopwatch(); // watch.Start(); // while (true) // { // try // { // var data = (string)redisDB.ListRightPop("200001"); // Console.WriteLine(data); // if (!string.IsNullOrEmpty(data)) // { // orderInforList.Add(data); // } // else // { // Console.WriteLine("暂时没有订单信息,休息一下"); // Thread.Sleep(2000); // } // if (orderInforList.Count() >= 100 || watch.ElapsedMilliseconds > 2000) // { // if (orderInforList.Count() > 0) // { // using (ESHOPContext db = new ESHOPContext()) // { // //1.扣减库存 // var sArctile = db.Set<T_SeckillArticle>().Where(u => u.id == "300001").FirstOrDefault(); // sArctile.articleStockNum = sArctile.articleStockNum - orderInforList.Count(); // //2. 插入订单信息 // foreach (var item in orderInforList) // { // List<string> tempData = item.Split('-').ToList(); // T_Order tOrder = new T_Order(); // tOrder.id = Guid.NewGuid().ToString("N"); // tOrder.userId = tempData[0]; // tOrder.orderNum = tempData[3]; // tOrder.articleId = tempData[1]; // tOrder.orderTotalPrice = Convert.ToDecimal(tempData[2]); // tOrder.addTime = DateTime.Now; // tOrder.orderStatus = 0; // db.Add<T_Order>(tOrder); // } // int count = db.SaveChanges(); // Console.WriteLine($"执行成功,条数为:{count}"); // } // } // else // { // Thread.Sleep(1000); // Console.WriteLine("接着休息"); // } // //统一:清空orderInforList的临时数据 和 重置时间 // orderInforList.Clear(); // watch.Reset(); // watch.Start(); // } // } // catch (Exception ex) // { // Console.WriteLine($"执行失败:{ex.Message}"); // } // } //} #endregion #region 03-EFCore调用SQL //{ // Console.WriteLine("下面开始执行消费业务"); // RedisHelp redisHelp = new RedisHelp("localhost:6379"); // var redisDB = redisHelp.GetDatabase(); // //临时存储从队列中取出来的信息 // List<string> orderInforList = new List<string>(); // Stopwatch watch = new Stopwatch(); // watch.Start(); // while (true) // { // try // { // var data = (string)redisDB.ListRightPop("200001"); // Console.WriteLine(data); // if (!string.IsNullOrEmpty(data)) // { // orderInforList.Add(data); // } // else // { // Console.WriteLine("暂时没有订单信息,休息一下"); // Thread.Sleep(2000); // } // if (orderInforList.Count() >= 100 || watch.ElapsedMilliseconds > 2000) // { // if (orderInforList.Count() > 0) // { // using (ESHOPContext db = new ESHOPContext()) // { // using (var transaction = db.Database.BeginTransaction()) // { // try // { // //1.扣减库存 // string sql1 = $"update T_SeckillArticle set articleStockNum=articleStockNum-{orderInforList.Count()} where id='300001';"; // db.Database.ExecuteSqlRaw(sql1); // //2. 插入订单信息 // string sql2 = ""; // foreach (var item in orderInforList) // { // List<string> tempData = item.Split('-').ToList(); // sql2 = sql2 + @$"insert into T_Order(id,userId,orderNum,articleId,orderTotalPrice,addTime,orderStatus) values" + // $"('{ Guid.NewGuid().ToString("N")}','{tempData[0]}','{tempData[3]}',{tempData[1]},'{ Convert.ToDecimal(tempData[2])}','{DateTime.Now}',0);"; // } // db.Database.ExecuteSqlRaw(sql2); // transaction.Commit(); // Console.WriteLine("提交成功"); // } // catch (Exception ex) // { // //using包裹事务,失败了会自动回滚 // Console.WriteLine($"提交失败:{ex.Message}"); // } // } // } // } // else // { // Thread.Sleep(1000); // Console.WriteLine("接着休息"); // } // //统一:清空orderInforList的临时数据 和 重置时间 // orderInforList.Clear(); // watch.Reset(); // watch.Start(); // } // } // catch (Exception ex) // { // Console.WriteLine($"执行失败:{ex.Message}"); // } // } //} #endregion #region 04-基于EFCore.BulkExtensions优化 //{ // Console.WriteLine("下面开始执行消费业务"); // RedisHelp redisHelp = new RedisHelp("localhost:6379"); // var redisDB = redisHelp.GetDatabase(); // //临时存储从队列中取出来的信息 // List<string> orderInforList = new List<string>(); // Stopwatch watch = new Stopwatch(); // watch.Start(); // while (true) // { // try // { // var data = (string)redisDB.ListRightPop("200001"); // Console.WriteLine(data); // if (!string.IsNullOrEmpty(data)) // { // orderInforList.Add(data); // } // else // { // Console.WriteLine("暂时没有订单信息,休息一下"); // Thread.Sleep(1000); // } // if (orderInforList.Count() >= 100 || watch.ElapsedMilliseconds > 2000) // { // if (orderInforList.Count() > 0) // { // using (ESHOPContext db = new ESHOPContext()) // { // //执行消费业务 // using (var transaction = db.Database.BeginTransaction()) // { // try // { // //1.扣减库存 // db.Set<T_SeckillArticle>().Where(u => u.id == "300001").BatchUpdate(a => new T_SeckillArticle { articleStockNum = a.articleStockNum - orderInforList.Count() }); // //2. 插入订单信息 // List<T_Order> insertOrderList = new List<T_Order>(); // foreach (var item in orderInforList) // { // List<string> tempData = item.Split('-').ToList(); // T_Order tOrder = new T_Order(); // tOrder.id = Guid.NewGuid().ToString("N"); // tOrder.userId = tempData[0]; // tOrder.orderNum = tempData[3]; // tOrder.articleId = tempData[1]; // tOrder.orderTotalPrice = Convert.ToDecimal(tempData[2]); // tOrder.addTime = DateTime.Now; // tOrder.orderStatus = 0; // insertOrderList.Add(tOrder); // } // db.BulkInsert(insertOrderList); // //统一提交事务 // transaction.Commit(); // Console.WriteLine($"消费成功。。。。"); // } // catch (Exception ex) // { // Console.WriteLine($"消费失败:{ex.Message}"); // } // } // } // } // else // { // Thread.Sleep(1000); // Console.WriteLine("接着休息"); // } // //统一:清空orderInforList的临时数据 和 重置时间 // orderInforList.Clear(); // watch.Reset(); // watch.Start(); // } // } // catch (Exception ex) // { // Console.WriteLine($"执行失败:{ex.Message}"); // } // } //} #endregion
!
- 作 者 : Yaopengfei(姚鹏飞)
- 博客地址 : http://www.cnblogs.com/yaopengfei/
- 声 明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
- 声 明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。