一对多验证竞争条件
One-to-many validation race condition
我有两个具有一对多关系的实体。
TripRequest.cs
public class TripRequest
{
public Guid Id { get; set; }
public Guid UserId { get; set; }
public User User { get; set; }
public Guid TripId { get; set; }
public Trip Trip { get; set; }
}
Trip.cs
public class Trip
{
public Guid Id { get; set; }
public ICollection <TripRequest> Requests { get; set; } = new List<TripRequest>();
}
我有一个命令,我想在其中检查行程是否包含来自用户的其他请求。
public void Handle(CreateRequestCommand command)
{
var trip = _tripRepository.GetWithInclude(t => t.Requests)
.FirstOrDefault(x => x.Id.Equals(command.TripId));
if (trip == null)
{
throw new EntityNotFoundException();
}
if (trip.Requests.Any(x => x.UserId.Equals(command.UserId)))
{
throw new ConflictException();
}
var request = new TripRequest
{
TripId = command.TripId,
UserId = command.UserId,
CreationDate = DateTime.Now
};
_requestRepository.Create(request);
}
在流A中检查通过并在流B中添加用户时存在竞争条件。接下来,在流A中添加具有相同UserId的用户。
我尝试使用 ConcurrencyCheck 属性,并且正在考虑 TripRequest 的复合键。
是否可以在数据库端进行此类检查?解决此问题的最佳方法是什么?
您不应该将此视为并发问题,因为您可以使用唯一的 constraint/unique 索引来绝对防止有两个 TripRequests 用于相同的 (TripId,UserId),例如:
[Index("UserId","TripId",IsUnique = true)]
public class TripRequest
{
public Guid Id { get; set; }
public Guid UserId { get; set; }
public User User { get; set; }
public Guid TripId { get; set; }
public Trip Trip { get; set; }
}
我有两个具有一对多关系的实体。
TripRequest.cs
public class TripRequest
{
public Guid Id { get; set; }
public Guid UserId { get; set; }
public User User { get; set; }
public Guid TripId { get; set; }
public Trip Trip { get; set; }
}
Trip.cs
public class Trip
{
public Guid Id { get; set; }
public ICollection <TripRequest> Requests { get; set; } = new List<TripRequest>();
}
我有一个命令,我想在其中检查行程是否包含来自用户的其他请求。
public void Handle(CreateRequestCommand command)
{
var trip = _tripRepository.GetWithInclude(t => t.Requests)
.FirstOrDefault(x => x.Id.Equals(command.TripId));
if (trip == null)
{
throw new EntityNotFoundException();
}
if (trip.Requests.Any(x => x.UserId.Equals(command.UserId)))
{
throw new ConflictException();
}
var request = new TripRequest
{
TripId = command.TripId,
UserId = command.UserId,
CreationDate = DateTime.Now
};
_requestRepository.Create(request);
}
在流A中检查通过并在流B中添加用户时存在竞争条件。接下来,在流A中添加具有相同UserId的用户。
我尝试使用 ConcurrencyCheck 属性,并且正在考虑 TripRequest 的复合键。 是否可以在数据库端进行此类检查?解决此问题的最佳方法是什么?
您不应该将此视为并发问题,因为您可以使用唯一的 constraint/unique 索引来绝对防止有两个 TripRequests 用于相同的 (TripId,UserId),例如:
[Index("UserId","TripId",IsUnique = true)]
public class TripRequest
{
public Guid Id { get; set; }
public Guid UserId { get; set; }
public User User { get; set; }
public Guid TripId { get; set; }
public Trip Trip { get; set; }
}