Browse Source

Complete only the reserved unit of work on response start

pull/26017/head
maliming 7 hours ago
parent
commit
4bd160565d
No known key found for this signature in database GPG Key ID: A646B9CB645ECEA4
  1. 7
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpUnitOfWorkMiddleware.cs
  2. 7
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Uow/UnitOfWorkMiddleware_Tests.cs
  3. 24
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Uow/UnitOfWorkTestController.cs

7
framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpUnitOfWorkMiddleware.cs

@ -39,12 +39,13 @@ public class AbpUnitOfWorkMiddleware : AbpMiddlewareBase, ITransientDependency
{
// Commit the ambient unit of work before the response starts, so data written
// during the request is committed before the response is flushed to the client.
// Only when this reserved unit of work is the current one: if an explicit nested
// unit of work is in progress, it is the current one and must be left to its owner.
context.Response.OnStarting(async () =>
{
var currentUow = _unitOfWorkManager.Current;
if (currentUow != null && !currentUow.IsCompleted)
if (_unitOfWorkManager.Current == uow)
{
await currentUow.CompleteAsync(_cancellationTokenProvider.Token);
await uow.CompleteAsync(_cancellationTokenProvider.Token);
}
});

7
framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Uow/UnitOfWorkMiddleware_Tests.cs

@ -68,4 +68,11 @@ public class UnitOfWorkMiddleware_Tests : AspNetCoreMvcTestBase
var body = await GetResponseAsStringAsync("/api/unitofwork-test/RawDatabaseProviderAfterResponseFlush");
body.ShouldBe("first:threw-AbpException");
}
[Fact]
public async Task Response_Flush_Inside_Nested_Uow_Should_Not_Complete_The_Nested_Uow()
{
var body = await GetResponseAsStringAsync("/api/unitofwork-test/NestedUowDuringResponseFlush");
body.ShouldBe("first:nested-completed-by-owner");
}
}

24
framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Uow/UnitOfWorkTestController.cs

@ -151,4 +151,28 @@ public class UnitOfWorkTestController : AbpController
await Response.WriteAsync(outcome);
}
[HttpGet]
[Route("NestedUowDuringResponseFlush")]
public async Task NestedUowDuringResponseFlush()
{
using (var nested = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: false))
{
await Response.WriteAsync("first");
await Response.Body.FlushAsync();
string outcome;
try
{
await nested.CompleteAsync();
outcome = ":nested-completed-by-owner";
}
catch (AbpException)
{
outcome = ":nested-already-completed";
}
await Response.WriteAsync(outcome);
}
}
}

Loading…
Cancel
Save