我在我的架构中使用 CQRS 方法,例如,我有一个如下命令:
public class ModifyDepartmentInformationCommand
{
public ModifyDepartmentInformationCommand() { }
public ModifyDepartmentInformationCommand(int departmentId, string departmentName, byte[] version)
{
DepartmentId = departmentId;
DepartmentName = departmentName;
Version = version;
}
public int DepartmentId { get; set; }
public string DepartmentName { get; set; }
public byte[] Version { get; set; }
}
它的处理程序看起来像:
public class ModifyDepartmentInformationCommandHandler :
IRequestHandler<ModifyDepartmentInformationCommand, ModifyDepartmentInformationCommandResult>
{
private readonly IMgpCommandContext _mgpCommandContext;
public ModifyDepartmentInformationCommandHandler(IMgpCommandContext mgpCommandContext)
{
_mgpCommandContext = mgpCommandContext;
}
public ModifyDepartmentInformationCommandResult Execute(ModifyDepartmentInformationCommand request)
{
new ModifyDepartmentInformationCommandValidator().ValidateAndThrow(request);
var department = _mgpCommandContext.Departments.SingleOrDefault(o => o.Id == request.DepartmentId);
if (department == null) { throw new ApplicationException("DepartmentDoesNotExist", "There is no such department."); }
department.ModifyInformation(request.Version, request.DepartmentName);
_mgpCommandContext.SaveChanges();
return new ModifyDepartmentInformationCommandResult();
}
}
如您所见,Version
用作并发 token 。它与命令一起传递,并在命令处理程序中传递给部门的域实体操作ModifyInformation,它设置版本:
public class Department
{
...
public void ModifyInformation(byte[] version, string departmentName)
{
Version = version;
Name = departmentName;
new DepartmentValidator().ValidateAndThrow(this);
}
}
因为 Department 域实体上的 Version 属性是使用 EF Code First 映射的,如下所示:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Department>().ToTable("Department").Property(p => p.Version).IsRowVersion().IsConcurrencyToken(); ;
}
...从在上下文上执行 SaveChanges 的那一刻起,就会正确检测到并发性。
这就是现在的工作方式...我的问题与我在部门级别有一个并发 token 这一事实有关。因此,如果我有每个修改部门不同属性的命令,则使用相同的并发 token 。
因此,如果两个用户查询部门X,用户1使用一条命令更改部门名称,用户2使用另一条命令更改部门的某些其他属性;那么提交该命令的第二个用户仍然可能会遇到并发冲突,即使它不是被修改的属性。
这是正确的方法,还是有更好的方法来处理命令中的并发性,例如对实体使用多个并发 token ?一般采取什么方法?
最佳答案
您选择了正确的方法。另外,您可以将部门配置拆分为多个逻辑部分,例如:公共(public)参数、安全性等。每个部分都将被单独考虑,并且每个部分都有自己的版本。
关于c# - 使用 CQRS 方法处理并发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25451610/