一. 前言
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. 最初版本
代碼分享:

#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
代碼分享:

/********************************************下面是解決--緩存問題導致庫存扣減錯誤的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上下文銷毀(最終版)
代碼分享:

/*******************************************調整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 : 原創博客請在轉載時保留原文鏈接或在文章開頭加上本人博客地址,否則保留追究法律責任的權利。