我們有一個電子商務網站,人們可以購買禮品卡。這些卡片存儲在一個表格中,並按整數排序以達到物流目的。如果有人購買禮品卡,我們會在數據庫中插入購買訂單,並編輯第一張符合條件的卡片的字段,以便知道該卡片不再可用。鎖表讀
但是有時候2個用戶在同一時間購買一張卡片時,兩張卡片都是相同的。所以我們與IsolationLevel.ReadCommitted
進行了交易,這是行不通的。對於4個同時點擊,對於2 PurchaseOrder
有1個相同的Card
,對於2 PurchaseOrder
有另外的Card
。
TransactionOptions transOption = new TransactionOptions();
transOption.IsolationLevel = IsolationLevel.ReadCommitted;
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, transOption))
{
PurchaseOrder purchaseOrder = GetFull(request.OrderId);
purchaseOrder.ChangeTracker.ChangeTrackingEnabled = true;
purchaseOrder.IdStatus = DbConstants.RefPurchaseOrderStatus.Completed;
//select the quantity of purchased gift cards and update them with ObjectContext.SaveChanges()
List<Card> cards = _cardBusiness.AssignCards(purchaseOrder.Quantity, purchaseOrder.IdProduct, purchaseOrder.IdUserAccount, purchaseOrder.IdChannel);
Card[] arrCards = cards.ToArray();
int count = 0;
//Set a link between a PurchaseOrder Line and the Card
foreach(PurchaseOrderLine line in purchaseOrder.PurchaseOrderLines)
{
line.ChangeTracker.ChangeTrackingEnabled = true;
line.IdCard = arrCards[count].Id;
count++;
}
PurchaseOrder po = Update(purchaseOrder);
scope.Complete();
return true;
}
快速評論:在交易中,我們得到了以前插入PurchaseOrder
,改變其狀態,然後選擇一個可用的禮品卡(S),編輯一些屬性,SaveChanges()
並返回禮品卡(一個或多個)鏈接到PurchaseOrderLine
。
但我們顯然沒有鎖定卡的選擇。我們怎麼能這樣做?
更新:
public static List<Card> AssignCards(int qty, int idProduct, Guid idUserAccount, int? idChannel)
{
using (RestopolitanEntities context = GetContext())
{
try
{
var Xcards = (from c in context.Cards
select c);
List<Card> cards = Xcards.OrderBy(c => c.IdOrder).Take(qty).ToList();
foreach (Card card in cards)
{
card.ChangeTracker.ChangeTrackingEnabled = true;
card.UseDate = DateTime.Now;
}
context.SaveChanges();
return cards.ToList();
}
catch (Exception ex)
{
HandleException(ex);
}
}
return null;
}
這一次,我與IsolationLevel.RepeatableRead
試過,一個Card
不會再歸因於2 PurchaseOrder
。但是沒有Card
從AssignCards()
返回。對於4個同時點擊,有2個PurchaseOrder
,其中有1個不同的Card
和2 PurchaseOrder
而沒有Card
。
什麼是AssignCards()?你可以添加這種方法的代碼? – MikkaRin
也許你可以創建一個數據庫序列的解決方案,因爲數據庫將小心,你沒有得到一個已經使用的號碼... – DatRid
你使用什麼數據庫平臺? – mjwills