【发布时间】:2019-06-09 08:36:51
【问题描述】:
我最近开始了一个使用 DDD 架构的新项目。对于相同的有界上下文,我有 2 个单独的数据库。我知道不同的有界上下文通过消息队列相互交谈。但是由于我在同一个有界上下文中具有查询和命令功能,所以我不知道如何同步读取模型和写入模型(在同一个有界上下文中)。
我将 NH 用于写入(命令)端,将 EF 用于读取(查询)端。我为 NH 使用了 Unit Of Work,并使用 Unit Of Work 修饰了我的所有命令,并使它们在每个聚合中都具有事务性:
public class NhUnitOfWork : IUnitOfWork
{
private readonly ISession _session;
public NhUnitOfWork(ISession session)
{
_session = session;
}
public void Begin()
{
_session.Transaction.Begin(IsolationLevel.ReadCommitted);
}
public void Commit()
{
_session.Transaction.Commit();
}
public void Rollback()
{
_session.Transaction.Rollback();
}
}
和事务装饰器:
public class TransactionalCommandHandlerDecorator<T>:ICommandHandler<T>
{
private ICommandHandler<T> _commandHandler;
private IUnitOfWork _unitOfWork;
public TransactionalCommandHandlerDecorator(ICommandHandler<T> commandHandler, IUnitOfWork unitOfWork)
{
_commandHandler = commandHandler;
_unitOfWork = unitOfWork;
}
public void Handle(T command)
{
_unitOfWork.Begin();
try
{
_commandHandler.Handle(command);
_unitOfWork.Commit();
}
catch (Exception exp)
{
_unitOfWork.Rollback();
throw;
}
}
}
所以在应用层,在创建命令中我必须编排业务流程:
public class CategoryCommandHandlers:ICommandHandler<CreateCategoryCommand>
{
private readonly ICategoryRepository _repository;
private readonly ICategoryQueryService _queryService;
public CategoryCommandHandlers(ICategoryRepository repository, ICategoryQueryService queryService)
{
_repository = repository;
_queryService = queryService;
}
public void Handle(CreateCategoryCommand command)
{
var categoryId = new CategoryId(Guid.NewGuid());
var parentId=new CategoryId(command.ParentId);
var category=new Category(categoryId,command.Name,parentId);
var parent = _repository.GetById(parentId);
if (parent==null)
throw new ParentCategoryNotFoundException();
_repository.Create(category);
var queryModel = new CategoryQuery(categoryId.Value, category.Name, parentId.Value);
_queryService.Create(queryModel);
}
}
但我不知道是什么问题。一切运行都没有一个错误,但我已读取保存到查询数据库中的模型并写入模型剂量。
如果我应该为读取模型使用单独的事务装饰器,我如何确保正确运行两个事务而不会出错?还是在发现错误时回滚?
或者命令完全错误,我不知道如何处理和同步读写!
【问题讨论】:
标签: c# domain-driven-design cqrs