netcorepal / netcorepal-cloud-framework

基于 ASP.NET Core 的领域驱动设计微服务架构实现方案
https://netcorepal.github.io/netcorepal-cloud-framework/
MIT License
115 stars 29 forks source link

领域事件处理函数中,数据库事务未生效 #17

Closed yc-2503 closed 5 months ago

yc-2503 commented 6 months ago

数据库PG 16

public class LotCreatedDomainEventHandler(ILotRepository lotRepository,IMediator mediator) : IDomainEventHandler<LotCreatedDomainEvent>
{
    public async Task Handle(LotCreatedDomainEvent notification, CancellationToken cancellationToken)
    {
        LotAddHistCmd cmd = new LotAddHistCmd(){TenantId = "1",OperatorId=1,OperatorLoginId="1",Lot=notification.Lot };
        LotHist lotHist = new(notification.Lot);
        await lotRepository.AddLotHistAsync(lotHist);
        await lotRepository.UnitOfWork.SaveEntitiesAsync();
    }
}

如果不添加 await lotRepository.UnitOfWork.SaveEntitiesAsync(); 数据库中就没有相关的记录。

如果改成在CommandHandler中,事务也是正常的

public class LotCreatedDomainEventHandler(ILotRepository lotRepository,IMediator mediator) : IDomainEventHandler<LotCreatedDomainEvent>
{
    public async Task Handle(LotCreatedDomainEvent notification, CancellationToken cancellationToken)
    {
        LotAddHistCmd cmd = new LotAddHistCmd(){TenantId = "1",OperatorId=1,OperatorLoginId="1",Lot=notification.Lot };

        await mediator.Send(cmd);
    }
}

public class LotAddHistHandler(ILotRepository lotRepository) : ICommandHandler<LotAddHistCmd, ResponseData>
{
    public async Task<ResponseData> Handle(LotAddHistCmd request, CancellationToken cancellationToken)
    {
        LotHist lotHist = new(request.Lot);
        await lotRepository.AddLotHistAsync(lotHist);
        return new ResponseData();
    }
}
witskeeper commented 6 months ago

这里是by design的,故意设计成这样。 领域事件的作用是触发命令,不应在领域事件中直接操作模型。 因此领域事件的处理不涉及事物的开关。