Architecture 在DDD环境下应如何处理交易
在DDD上下文中,当您处理域事件时,事务应该从何处开始和结束 基础设施层具有UoW实现Architecture 在DDD环境下应如何处理交易,architecture,transactions,domain-driven-design,software-design,unit-of-work,Architecture,Transactions,Domain Driven Design,Software Design,Unit Of Work,在DDD上下文中,当您处理域事件时,事务应该从何处开始和结束 基础设施层具有UoW实现 /// => configured via DI as Per Request class UnitOfWork : IUnitOfWork { ITransaction _transaction; static ISessionFactory _factory; ISession _session UnitOfWork() { _
/// => configured via DI as Per Request
class UnitOfWork : IUnitOfWork
{
ITransaction _transaction;
static ISessionFactory _factory;
ISession _session
UnitOfWork()
{
_session = _factory.OpenSession();
_transaction = _session.BeginTransaction(); ///=> start transaction
}
void Commit()
{
try
_transaction.Commit();
catch
_transaction.Rollback();
finally
Dispose();
}
}
应用层用例处理程序
class SomeAppServiceUseCaseHandler : IUseCaseHandler
{
IUnitOfWork _uow;
ISomeRepo _repo;
AppService(IUnitOfWork uow, ISomeRepo repo)
{
_uow = uow;
_repo = repo;
}
void UseCaseHandler(Request request)
{
SomeAggregate agg = _repo.GetAggregate(request.Id)
agg.DoSomethingToChangeState();
_repo.UpdateAgg(agg);
_uow.Commit(agg); ///=> commit changes for this transaction success
}
}
在Domain.Layer中,该方法还将向聚合的域事件列表添加Domain.Event
SomeAggregate : AggregateRoot
{
DoSomethingToChangeState()
{
.... do something
var someObject;
base.AddEvent(new SomethingHappenedEvent(someObject)));
}
}
Application.Layer具有Domain.Event处理程序
class SomethingHappenedEventHander : Handler<SomethingHappenedEvent>
{
IRepo repo;
IUnitOfWork _uow;
DomainEventHander(IRepo repo, IUnitOfWork uow)
{
_repo = repo;
_uow= uow;
}
HandleEvent(someObject)
{
AnotherAggregate agg = new AnotherAggregate ();
agg.DoSomeCommand(someObject);
_repo.Create(agg);
_uow.Commit(); ///=> commit changes for same transaction fail, should rollback prev transaction as well
}
}
class SomethingHappendEventHander:Handler
{
IRepo回购;
工作单元;
DomainEventHander(IRepo回购协议,IUnitOfWork uow)
{
_回购=回购;
_uow=uow;
}
HandleEvent(someObject)
{
AnotherAggregate agg=新的AnotherAggregate();
agg.DoSomeCommand(someObject);
_回购创建(agg);
_提交();//=>提交同一事务的更改失败,也应回滚上一个事务
}
}
我觉得这不对
那么,如何正确处理这两种情况呢 如Constantin所述,每个命令只能更新一个聚合。为什么?因为通过更新一个事务中的多个聚合,会降低系统的吞吐量。数据库事务边界越大,在写入数据时越有可能面临争用,因此希望尽可能保持事务的细粒度 关于你的问题:
DDD声明每个事务只应修改一个聚合。是的,这是真的,但如何处理多个聚合更新?我认为我不应该在Saga/processmanager中的Application.Layer usecasehandler中开始事务。如果需要回滚聚合,则边界有问题,或者需要将其建模为业务流程
_repo.Save(agg);