心悸寶貝 BUG 系列 #1 — 小小的失誤,大大的損失
2026-03-21 22:35:41
當我發現這段 Code 的時候,DB 裡已經寫了一堆不該存在的資料——當然還有錢包的問題
我先哈哈大笑,然後心悸寶貝,然後趕快 Hotfix。
我直接分享一段程式碼,讓各位看一下能不能找出問題,問題總共有兩個
```csharp
do
{
using (var transaction = _dbContext.Database.BeginTransaction())
{
using (var dbContext = new OrderDbContext(OrderDbContextHelper.GetConnectionString()))
{
var pendingItem = dbContext.PendingDispatchItems
.FirstOrDefault(r => r.BatchId == batchId
&& r.IsDispatched == false
&& !retryItemIds.Contains(r.Id));
if (pendingItem == null)
{
if (retryItemIds.HasItems())
{
logger.Debug("出貨完畢,開始重試失敗項目");
retryItemIds = new List<int>();
continue;
}
else
{
logger.Debug("所有出貨項目處理完畢");
break;
}
}
try
{
var order = dbContext.Orders
.FirstOrDefault(r => r.Id == pendingItem.OrderId);
var now = DateTimeOffset.UtcNow;
dbContext.SP_Inventory_Deduct(order.ProductId, pendingItem.Quantity, now);
var dispatchRecord = dbContext.DispatchRecords
.FirstOrDefault(r => r.Id == dispatchRecordId);
var tran = new OrderTransaction
{
Order = order,
Time = now,
Type = TransactionType.Dispatch,
Amount = pendingItem.Quantity,
Memo = dispatchRecord.Note,
};
var detail = new DispatchDetail
{
DispatchRecordId = dispatchRecord.Id,
OrderId = order.Id,
Quantity = pendingItem.Quantity,
TransactionId = tran.Id,
};
dbContext.OrderTransactions.Add(tran);
dbContext.DispatchDetails.Add(detail);
pendingItem.IsDispatched = true;
dbContext.SaveChanges();
transaction.Commit();
}
catch (Exception ex)
{
logger.Fatal(ex, $"出貨失敗:[{pendingItem.Id}] {ex.GetBaseException().Message}");
transaction.Rollback();
var resetCount = 20;
if (retryItemIds.Count() < resetCount)
{
logger.Debug($"項目 [{pendingItem.Id}] 加入重試清單");
retryItemIds.Add(pendingItem.Id);
}
else
{
logger.Debug($"重試清單已達 {resetCount},清空後繼續");
retryItemIds = new List<int>();
}
continue;
}
}
}
} while (true);
```
不知道各位有沒有看出來,其實蠻難發現的 XD,這是我們公司系統古老的 Code,而他卻造成巨大的損失
首先它用建構式注入的 _dbContext 開了 Transaction,卻又 new 了新的 dbContext
而且都用新的 dbContext 去儲存資料——那只要有一個步驟 Exception
transaction.Rollback() 基本上啥都沒有 Rollback 到,中途存的資料都已經存了
再來是只要發生錯誤它就會無限 Retry,然後在相同的地方繼續噴 Exception,直到有人發現為止!!
讓我難忘的是它造成的巨大的損失,但其實只要眼尖一點就可以看到這個問題
當然現在把它拿去問 AI 它馬上就發現了,還會給它嚴重錯誤的評分
這種類型的錯誤如果是用 AI 寫的,我認為是不可能再出現,是人寫的就有可能 XD
近代工程師仍舊要保持著細心,只是以前可能是寫 Code 要細心
現在 AI 可以幫你抓 code 裡的 bug,但它沒辦法幫你確認規格與現實是否不符——
當然,也沒辦法幫你善後那堆不該存在的資料就是了 😅
點擊複製文章連結