From 90d246fd7e4a02238a945620bbc5812985de8208 Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 25 May 2023 16:24:57 +0800 Subject: [PATCH] Add `CancellationToken` to `ITransactionApi`. Resolve #16646 --- .../EfCoreTransactionApi.cs | 6 ++-- .../Abp/Uow/MongoDB/MongoDbTransactionApi.cs | 4 +-- .../Volo/Abp/Uow/ISupportsRollback.cs | 2 +- .../Volo/Abp/Uow/ITransactionApi.cs | 3 +- .../Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWork.cs | 6 ++-- .../Uow/UnitOfWork_CancellationToken_Tests.cs | 29 +++++++++++++++++ .../Uow/UnitOfWork_CancellationToken_Tests.cs | 31 +++++++++++++++++++ 7 files changed, 71 insertions(+), 10 deletions(-) create mode 100644 framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Uow/UnitOfWork_CancellationToken_Tests.cs create mode 100644 framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Uow/UnitOfWork_CancellationToken_Tests.cs diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/EfCoreTransactionApi.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/EfCoreTransactionApi.cs index 8979925f0a..02177142cd 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/EfCoreTransactionApi.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/EfCoreTransactionApi.cs @@ -28,7 +28,7 @@ public class EfCoreTransactionApi : ITransactionApi, ISupportsRollback AttendedDbContexts = new List(); } - public async Task CommitAsync() + public async Task CommitAsync(CancellationToken cancellationToken = default) { foreach (var dbContext in AttendedDbContexts) { @@ -38,10 +38,10 @@ public class EfCoreTransactionApi : ITransactionApi, ISupportsRollback continue; //Relational databases use the shared transaction if they are using the same connection } - await dbContext.Database.CommitTransactionAsync(CancellationTokenProvider.Token); + await dbContext.Database.CommitTransactionAsync(CancellationTokenProvider.FallbackToProvider(cancellationToken)); } - await DbContextTransaction.CommitAsync(CancellationTokenProvider.Token); + await DbContextTransaction.CommitAsync(CancellationTokenProvider.FallbackToProvider(cancellationToken)); } public void Dispose() diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/MongoDbTransactionApi.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/MongoDbTransactionApi.cs index e5b1468e14..8fc4b2615a 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/MongoDbTransactionApi.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/MongoDbTransactionApi.cs @@ -19,9 +19,9 @@ public class MongoDbTransactionApi : ITransactionApi, ISupportsRollback CancellationTokenProvider = cancellationTokenProvider; } - public async Task CommitAsync() + public async Task CommitAsync(CancellationToken cancellationToken) { - await SessionHandle.CommitTransactionAsync(CancellationTokenProvider.Token); + await SessionHandle.CommitTransactionAsync(CancellationTokenProvider.FallbackToProvider(cancellationToken)); } public void Dispose() diff --git a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/ISupportsRollback.cs b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/ISupportsRollback.cs index cb0f33f7db..c6be103781 100644 --- a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/ISupportsRollback.cs +++ b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/ISupportsRollback.cs @@ -5,5 +5,5 @@ namespace Volo.Abp.Uow; public interface ISupportsRollback { - Task RollbackAsync(CancellationToken cancellationToken); + Task RollbackAsync(CancellationToken cancellationToken = default); } diff --git a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/ITransactionApi.cs b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/ITransactionApi.cs index ddb6506917..fa156332c1 100644 --- a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/ITransactionApi.cs +++ b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/ITransactionApi.cs @@ -1,9 +1,10 @@ using System; +using System.Threading; using System.Threading.Tasks; namespace Volo.Abp.Uow; public interface ITransactionApi : IDisposable { - Task CommitAsync(); + Task CommitAsync(CancellationToken cancellationToken = default); } diff --git a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWork.cs b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWork.cs index 8713b2ec7b..626c74478b 100644 --- a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWork.cs +++ b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWork.cs @@ -158,7 +158,7 @@ public class UnitOfWork : IUnitOfWork, ITransientDependency await SaveChangesAsync(cancellationToken); } - await CommitTransactionsAsync(); + await CommitTransactionsAsync(cancellationToken); IsCompleted = true; await OnCompletedAsync(); } @@ -363,11 +363,11 @@ public class UnitOfWork : IUnitOfWork, ITransientDependency } } - protected virtual async Task CommitTransactionsAsync() + protected virtual async Task CommitTransactionsAsync(CancellationToken cancellationToken) { foreach (var transaction in GetAllActiveTransactionApis()) { - await transaction.CommitAsync(); + await transaction.CommitAsync(cancellationToken); } } diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Uow/UnitOfWork_CancellationToken_Tests.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Uow/UnitOfWork_CancellationToken_Tests.cs new file mode 100644 index 0000000000..1bec4ac13a --- /dev/null +++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Uow/UnitOfWork_CancellationToken_Tests.cs @@ -0,0 +1,29 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.TestApp.Domain; +using Volo.Abp.Uow; +using Xunit; + +namespace Volo.Abp.EntityFrameworkCore.Uow; + +public class UnitOfWork_CancellationToken_Tests : EntityFrameworkCoreTestBase +{ + [Fact] + public async Task Should_Cancel_Test() + { + using (var uow = GetRequiredService().Begin(isTransactional: true)) + { + await Assert.ThrowsAsync(async () => + { + var cst = new CancellationTokenSource(); + cst.Cancel(); + + await GetRequiredService>().InsertAsync(new Person(Guid.NewGuid(), "Adam", 42)); + + await uow.CompleteAsync(cst.Token); + }); + } + } +} diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Uow/UnitOfWork_CancellationToken_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Uow/UnitOfWork_CancellationToken_Tests.cs new file mode 100644 index 0000000000..d41379e15b --- /dev/null +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Uow/UnitOfWork_CancellationToken_Tests.cs @@ -0,0 +1,31 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.TestApp.Domain; +using Volo.Abp.TestApp.Testing; +using Volo.Abp.Uow; +using Xunit; + +namespace Volo.Abp.MongoDB.Uow; + +[Collection(MongoTestCollection.Name)] +public class UnitOfWork_CancellationToken_Tests : TestAppTestBase +{ + [Fact] + public async Task Should_Cancel_Test() + { + using (var uow = GetRequiredService().Begin(isTransactional: true)) + { + await Assert.ThrowsAsync(async () => + { + var cst = new CancellationTokenSource(); + cst.Cancel(); + + await GetRequiredService>().InsertAsync(new Person(Guid.NewGuid(), "Adam", 42)); + + await uow.CompleteAsync(cst.Token); + }); + } + } +}