diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/DbContextCreationContext.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/DbContextCreationContext.cs index 2b65b199a1..779aa32391 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/DbContextCreationContext.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/DbContextCreationContext.cs @@ -13,7 +13,7 @@ namespace Volo.Abp.EntityFrameworkCore.DependencyInjection public string ConnectionString { get; } - public DbConnection ExistingConnection { get; set; } + public DbConnection ExistingConnection { get; internal set; } public DbContextCreationContext(string connectionStringName, string connectionString) { 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 ce9afacef1..5e6669a6f5 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 @@ -34,9 +34,10 @@ namespace Volo.Abp.Uow.EntityFrameworkCore foreach (var dbContext in AttendedDbContexts) { - if (dbContext.As().HasRelationalTransactionManager()) + if (dbContext.As().HasRelationalTransactionManager() && + dbContext.Database.GetDbConnection() == DbContextTransaction.GetDbTransaction().Connection) { - continue; //Relational databases use the shared transaction + continue; //Relational databases use the shared transaction if they are using the same connection } await dbContext.Database.CommitTransactionAsync(CancellationTokenProvider.Token); @@ -54,9 +55,10 @@ namespace Volo.Abp.Uow.EntityFrameworkCore foreach (var dbContext in AttendedDbContexts) { - if (dbContext.As().HasRelationalTransactionManager()) + if (dbContext.As().HasRelationalTransactionManager() && + dbContext.Database.GetDbConnection() == DbContextTransaction.GetDbTransaction().Connection) { - continue; //Relational databases use the shared transaction + continue; //Relational databases use the shared transaction if they are using the same connection } await dbContext.Database.RollbackTransactionAsync(CancellationTokenProvider.FallbackToProvider(cancellationToken)); diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/UnitOfWorkDbContextProvider.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/UnitOfWorkDbContextProvider.cs index 07f1d200aa..388f1c4175 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/UnitOfWorkDbContextProvider.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/UnitOfWorkDbContextProvider.cs @@ -105,6 +105,7 @@ namespace Volo.Abp.Uow.EntityFrameworkCore return (TDbContext)((EfCoreDatabaseApi)databaseApi).DbContext; } + [Obsolete("Use CreateDbContextAsync method.")] private TDbContext CreateDbContext(IUnitOfWork unitOfWork, string connectionStringName, string connectionString) { var creationContext = new DbContextCreationContext(connectionStringName, connectionString); @@ -145,6 +146,7 @@ namespace Volo.Abp.Uow.EntityFrameworkCore } } + [Obsolete("Use CreateDbContextAsync.")] private TDbContext CreateDbContext(IUnitOfWork unitOfWork) { return unitOfWork.Options.IsTransactional @@ -159,6 +161,7 @@ namespace Volo.Abp.Uow.EntityFrameworkCore : unitOfWork.ServiceProvider.GetRequiredService(); } + [Obsolete("Use CreateDbContextWithTransactionAsync.")] private TDbContext CreateDbContextWithTransaction(IUnitOfWork unitOfWork) { var transactionApiKey = $"EntityFrameworkCore_{DbContextCreationContext.Current.ConnectionString}"; @@ -191,7 +194,24 @@ namespace Volo.Abp.Uow.EntityFrameworkCore if (dbContext.As().HasRelationalTransactionManager()) { - dbContext.Database.UseTransaction(activeTransaction.DbContextTransaction.GetDbTransaction()); + if (dbContext.Database.GetDbConnection() == DbContextCreationContext.Current.ExistingConnection) + { + dbContext.Database.UseTransaction(activeTransaction.DbContextTransaction.GetDbTransaction()); + } + else + { + /* User did not re-use the ExistingConnection and we are starting a new transaction. + * EfCoreTransactionApi will check the connection string match and separately + * commit/rollback this transaction over the DbContext instance. */ + if (unitOfWork.Options.IsolationLevel.HasValue) + { + dbContext.Database.BeginTransaction(unitOfWork.Options.IsolationLevel.Value); + } + else + { + dbContext.Database.BeginTransactionAsync(); + } + } } else { @@ -239,7 +259,29 @@ namespace Volo.Abp.Uow.EntityFrameworkCore if (dbContext.As().HasRelationalTransactionManager()) { - await dbContext.Database.UseTransactionAsync(activeTransaction.DbContextTransaction.GetDbTransaction(), GetCancellationToken()); + if (dbContext.Database.GetDbConnection() == DbContextCreationContext.Current.ExistingConnection) + { + await dbContext.Database.UseTransactionAsync(activeTransaction.DbContextTransaction.GetDbTransaction(), GetCancellationToken()); + } + else + { + /* User did not re-use the ExistingConnection and we are starting a new transaction. + * EfCoreTransactionApi will check the connection string match and separately + * commit/rollback this transaction over the DbContext instance. */ + if (unitOfWork.Options.IsolationLevel.HasValue) + { + await dbContext.Database.BeginTransactionAsync( + unitOfWork.Options.IsolationLevel.Value, + GetCancellationToken() + ); + } + else + { + await dbContext.Database.BeginTransactionAsync( + GetCancellationToken() + ); + } + } } else {