可靠的字典和交易提交
问题描述:
我在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();
}
答
要修改的内存实体而这正是存储在字典中。在修改任何属性之前,您需要制作对象的副本。这在几个地方有记录,但在这篇文章https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-work-with-reliable-collections中特别提到的常见陷阱部分。
而不是
VAR seatEntry = match.Value
做
VAR seatEntry =新SeatEntryType(match.Value)//假设拷贝构造函数
您好托德,我实际上已经尝试过了,并且回到了这种方法,因为那也不管用。我要重新检查。我在一个例子中下载的WebReferenceApp列出了这个方法,所以我尝试了它。 –
啊!我看到了我的错误。我在更新内存中对象后克隆了条目。我应该先克隆然后修改它。改变代码行来解决它。 –