2017-08-04 89 views
0

我在Reliable Dictionary中遇到了一个问题,我更新了一个特定的条目,但不提交事务。看起来事务中止不会重置更新的条目。可靠的字典和交易提交

在我的逻辑中,我必须检查几个座位是否在可靠的字典中可用。如果是,我将它们分配给订单。如果其中一个不可用,我理想中止交易,以确保先前分配的座位会回滚到原始状态,因为我没有提交交易。

我可以在这里做错吗?

这是我建立的代码:

  var unavailableSeats = new List<string>(); 
      using (var tx = StateManager.CreateTransaction()) 
      { 

       foreach (var requestSeat in request.Seats) 
       { 
        var match = await dict.Value.TryGetValueAsync(tx, requestSeat.ToString(), LockMode.Update); 
        if (!match.HasValue) 
        { 
         response.SetError($"No Seat found matching the Seat Key: {requestSeat} provided."); 
         return response; 
        } 

        var seatEntry = match.Value; 
        if (seatEntry.IsAvailable()) 
        { 
         seatEntry.AssignToOrder(request.OrderId, request.RequestId.ToString()); 
         await dict.Value.SetAsync(tx, requestSeat.ToString(), seatEntry, TimeSpan.FromSeconds(4), 
          cancellationToken); 
        } 
        else 
        { 
         unavailableSeats.Add(requestSeat.ToString()); 
        } 
       } 

       if (!unavailableSeats.Any()) 
       { 
        await tx.CommitAsync(); 
        response.Success = true; 
        response.RequestId = request.RequestId; 
        return response; 
       } 

       tx.Abort(); 
      } 

回答

1

要修改的内存实体而这正是存储在字典中。在修改任何属性之前,您需要制作对象的副本。这在几个地方有记录,但在这篇文章https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-work-with-reliable-collections中特别提到的常见陷阱部分。

而不是

VAR seatEntry = match.Value

VAR seatEntry =新SeatEntryType(match.Value)//假设拷贝构造函数

+0

您好托德,我实际上已经尝试过了,并且回到了这种方法,因为那也不管用。我要重新检查。我在一个例子中下载的WebReferenceApp列出了这个方法,所以我尝试了它。 –

+0

啊!我看到了我的错误。我在更新内存中对象后克隆了条目。我应该先克隆然后修改它。改变代码行来解决它。 –