我们有一个电子商务网站,人们可以购买礼品卡。这些卡片存储在一个表格中,并按整数排序以达到物流目的。如果有人购买礼品卡,我们会在数据库中插入购买订单,并编辑第一张符合条件的卡片的字段,以便知道该卡片不再可用。锁表读
但是有时候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