Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用于读取的锁表_C#_Sql_Entity Framework_Locking_Transactionscope - Fatal编程技术网

C# 用于读取的锁表

C# 用于读取的锁表,c#,sql,entity-framework,locking,transactionscope,C#,Sql,Entity Framework,Locking,Transactionscope,我们有一个电子商务网站,人们可以在那里购买礼品卡。这些卡存储在一个表中,并按整数排序,以便于逻辑操作。如果有人买了一张礼品卡,我们会在数据库中插入一张采购订单,并编辑第一张合格卡的字段,以便知道它不再可用 但有时当两个用户同时购买一张卡时,两个用户都会获得相同的卡。因此,我们使用IsolationLevel.ReadCommitted进行了一个事务,但该事务不起作用。对于4次同时单击,2次采购订单有1张相同的卡,2次采购订单有另一张卡 TransactionOptions transOption

我们有一个电子商务网站,人们可以在那里购买礼品卡。这些卡存储在一个表中,并按整数排序,以便于逻辑操作。如果有人买了一张礼品卡,我们会在数据库中插入一张采购订单,并编辑第一张合格卡的字段,以便知道它不再可用

但有时当两个用户同时购买一张卡时,两个用户都会获得相同的卡。因此,我们使用
IsolationLevel.ReadCommitted
进行了一个事务,但该事务不起作用。对于4次同时单击,2次
采购订单
有1张相同的
,2次
采购订单
有另一张

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;
}

这次我尝试了使用
IsolationLevel.RepeatableRead
,一张
卡不再归属于2
PurchaseOrder
。但是,
AssignCards()
没有返回任何
Card
。对于4次同时单击,有2次
PurchaseOrder
与1张不同的
Card
和2次
PurchaseOrder
Card

在交易开始时获取应用程序锁

context.Database.ExecuteSqlCommand("exec sp_getapplock 'AssignCards','Exclusive';");
或者在识别要使用的卡的查询上使用一些锁定提示:

var sql = "select top (@qty) CardId from Cards with (rowlock, updlock, readpast) where UseDate is null";
var cardIds = context.Database.SqlQuery<int>(sql,qty).ToList();

List<Card> cards = context.Cards.Where(c => cardIds.Contains(c.CardId)).ToList();
var sql=“从使用日期为空的(rowlock、updlock、readpass)卡片中选择top(@qty)cardd”;
var cardds=context.Database.SqlQuery(sql,qty.ToList();
List cards=context.cards.Where(c=>cardds.Contains(c.cardd)).ToList();

如果使用锁定提示,则可以使用readpass提示允许并发会话跳过被其他会话锁定的卡。如果你使用Apple锁,你可以在事务中间释放锁(在选择卡之后)。< /P>什么是分配卡()?您可以添加此方法的代码吗?也许您可以创建一个具有数据库序列的解决方案,因为db会注意您不会获得已使用的编号…您使用的是什么数据库平台?SQL Server 2014 Entity Framework 6
var sql = "select top (@qty) CardId from Cards with (rowlock, updlock, readpast) where UseDate is null";
var cardIds = context.Database.SqlQuery<int>(sql,qty).ToList();

List<Card> cards = context.Cards.Where(c => cardIds.Contains(c.CardId)).ToList();