From cc5fa9ed1f913c6d091cd30b15ddbbba318acc76 Mon Sep 17 00:00:00 2001 From: maliming Date: Tue, 23 Nov 2021 11:05:50 +0800 Subject: [PATCH 1/3] Log errors and not using if the current database does not support transactions eg: SQLite. --- .../UnitOfWorkDbContextProvider.cs | 204 +++++++++++++----- .../UnitOfWorkMongoDbContextProvider.cs | 6 +- 2 files changed, 156 insertions(+), 54 deletions(-) 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 e5e4c2584a..dce926412c 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 @@ -18,6 +18,8 @@ namespace Volo.Abp.Uow.EntityFrameworkCore public class UnitOfWorkDbContextProvider : IDbContextProvider where TDbContext : IEfCoreDbContext { + private const string TransactionsNotSupportedErrorMessage = "The current database does not support transactions, All operations will be performed in non-transactions, This may cause errors."; + public ILogger> Logger { get; set; } private readonly IUnitOfWorkManager _unitOfWorkManager; @@ -170,19 +172,34 @@ namespace Volo.Abp.Uow.EntityFrameworkCore { var dbContext = unitOfWork.ServiceProvider.GetRequiredService(); - var dbtransaction = unitOfWork.Options.IsolationLevel.HasValue - ? dbContext.Database.BeginTransaction(unitOfWork.Options.IsolationLevel.Value) - : dbContext.Database.BeginTransaction(); - - unitOfWork.AddTransactionApi( - transactionApiKey, - new EfCoreTransactionApi( - dbtransaction, - dbContext, - _cancellationTokenProvider - ) - ); - + try + { + var dbtransaction = unitOfWork.Options.IsolationLevel.HasValue + ? dbContext.Database.BeginTransaction(unitOfWork.Options.IsolationLevel.Value) + : dbContext.Database.BeginTransaction(); + + unitOfWork.AddTransactionApi( + transactionApiKey, + new EfCoreTransactionApi( + dbtransaction, + dbContext, + _cancellationTokenProvider + ) + ); + } + catch (Exception e) + { + if (e is InvalidOperationException || e is NotSupportedException) + { + Logger.LogError(TransactionsNotSupportedErrorMessage); + Logger.LogException(e); + } + else + { + throw; + } + } + return dbContext; } else @@ -199,25 +216,59 @@ namespace Volo.Abp.Uow.EntityFrameworkCore } 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) + try { - dbContext.Database.BeginTransaction(unitOfWork.Options.IsolationLevel.Value); + /* 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.BeginTransaction(); + } } - else + catch (Exception e) { - dbContext.Database.BeginTransaction(); + if (e is InvalidOperationException || e is NotSupportedException) + { + Logger.LogError(TransactionsNotSupportedErrorMessage); + Logger.LogException(e); + + return dbContext; + } + else + { + throw; + } } } } else { - /* No need to store the returning IDbContextTransaction for non-relational databases - * since EfCoreTransactionApi will handle the commit/rollback over the DbContext instance. - */ - dbContext.Database.BeginTransaction(); + try + { + /* No need to store the returning IDbContextTransaction for non-relational databases + * since EfCoreTransactionApi will handle the commit/rollback over the DbContext instance. + */ + dbContext.Database.BeginTransaction(); + } + catch (Exception e) + { + if (e is InvalidOperationException || e is NotSupportedException) + { + Logger.LogError(TransactionsNotSupportedErrorMessage); + Logger.LogException(e); + + return dbContext; + } + else + { + throw; + } + } } activeTransaction.AttendedDbContexts.Add(dbContext); @@ -235,18 +286,33 @@ namespace Volo.Abp.Uow.EntityFrameworkCore { var dbContext = unitOfWork.ServiceProvider.GetRequiredService(); - var dbTransaction = unitOfWork.Options.IsolationLevel.HasValue - ? await dbContext.Database.BeginTransactionAsync(unitOfWork.Options.IsolationLevel.Value, GetCancellationToken()) - : await dbContext.Database.BeginTransactionAsync(GetCancellationToken()); - - unitOfWork.AddTransactionApi( - transactionApiKey, - new EfCoreTransactionApi( - dbTransaction, - dbContext, - _cancellationTokenProvider - ) - ); + try + { + var dbTransaction = unitOfWork.Options.IsolationLevel.HasValue + ? await dbContext.Database.BeginTransactionAsync(unitOfWork.Options.IsolationLevel.Value, GetCancellationToken()) + : await dbContext.Database.BeginTransactionAsync(GetCancellationToken()); + + unitOfWork.AddTransactionApi( + transactionApiKey, + new EfCoreTransactionApi( + dbTransaction, + dbContext, + _cancellationTokenProvider + ) + ); + } + catch (Exception e) + { + if (e is InvalidOperationException || e is NotSupportedException) + { + Logger.LogError(TransactionsNotSupportedErrorMessage); + Logger.LogException(e); + } + else + { + throw; + } + } return dbContext; } @@ -264,30 +330,64 @@ namespace Volo.Abp.Uow.EntityFrameworkCore } 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) + try { - await dbContext.Database.BeginTransactionAsync( - unitOfWork.Options.IsolationLevel.Value, - GetCancellationToken() - ); + /* 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 + catch (Exception e) { - await dbContext.Database.BeginTransactionAsync( - GetCancellationToken() - ); + if (e is InvalidOperationException || e is NotSupportedException) + { + Logger.LogError(TransactionsNotSupportedErrorMessage); + Logger.LogException(e); + + return dbContext; + } + else + { + throw; + } } } } else { - /* No need to store the returning IDbContextTransaction for non-relational databases - * since EfCoreTransactionApi will handle the commit/rollback over the DbContext instance. - */ - await dbContext.Database.BeginTransactionAsync(GetCancellationToken()); + try + { + /* No need to store the returning IDbContextTransaction for non-relational databases + * since EfCoreTransactionApi will handle the commit/rollback over the DbContext instance. + */ + await dbContext.Database.BeginTransactionAsync(GetCancellationToken()); + } + catch (Exception e) + { + if (e is InvalidOperationException || e is NotSupportedException) + { + Logger.LogError(TransactionsNotSupportedErrorMessage); + Logger.LogException(e); + + return dbContext; + } + else + { + throw; + } + } } activeTransaction.AttendedDbContexts.Add(dbContext); diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs index 13025db2bc..3b492b1026 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs @@ -17,6 +17,8 @@ namespace Volo.Abp.Uow.MongoDB public class UnitOfWorkMongoDbContextProvider : IMongoDbContextProvider where TMongoDbContext : IAbpMongoDbContext { + private const string TransactionsNotSupportedErrorMessage = "The current database does not support transactions, All operations will be performed in non-transactions, This may cause errors."; + public ILogger> Logger { get; set; } private readonly IUnitOfWorkManager _unitOfWorkManager; @@ -190,7 +192,7 @@ namespace Volo.Abp.Uow.MongoDB } catch (NotSupportedException e) { - Logger.LogError("The current MongoDB database does not support transactions, All operations will be performed in non-transactions, This may cause errors."); + Logger.LogError(TransactionsNotSupportedErrorMessage); Logger.LogException(e); dbContext.ToAbpMongoDbContext().InitializeDatabase(database, client, null); @@ -241,7 +243,7 @@ namespace Volo.Abp.Uow.MongoDB } catch (NotSupportedException e) { - Logger.LogError("The current MongoDB database does not support transactions, All operations will be performed in non-transactions, This may cause errors."); + Logger.LogError(TransactionsNotSupportedErrorMessage); Logger.LogException(e); dbContext.ToAbpMongoDbContext().InitializeDatabase(database, client, null); From 046059f6662ec66c4a9609fc9434419ad295f880 Mon Sep 17 00:00:00 2001 From: maliming Date: Tue, 30 Nov 2021 11:19:07 +0800 Subject: [PATCH 2/3] Update `TransactionsNotSupportedErrorMessage` --- .../Abp/Uow/EntityFrameworkCore/UnitOfWorkDbContextProvider.cs | 2 +- .../Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) 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 dce926412c..245c3a3d70 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 @@ -18,7 +18,7 @@ namespace Volo.Abp.Uow.EntityFrameworkCore public class UnitOfWorkDbContextProvider : IDbContextProvider where TDbContext : IEfCoreDbContext { - private const string TransactionsNotSupportedErrorMessage = "The current database does not support transactions, All operations will be performed in non-transactions, This may cause errors."; + private const string TransactionsNotSupportedErrorMessage = "Current database does not support transactions. Your database may remain in an inconsistent state in an error case."; public ILogger> Logger { get; set; } diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs index 3b492b1026..206e9e2875 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs @@ -17,8 +17,7 @@ namespace Volo.Abp.Uow.MongoDB public class UnitOfWorkMongoDbContextProvider : IMongoDbContextProvider where TMongoDbContext : IAbpMongoDbContext { - private const string TransactionsNotSupportedErrorMessage = "The current database does not support transactions, All operations will be performed in non-transactions, This may cause errors."; - + private const string TransactionsNotSupportedErrorMessage = "Current database does not support transactions. Your database may remain in an inconsistent state in an error case."; public ILogger> Logger { get; set; } private readonly IUnitOfWorkManager _unitOfWorkManager; From a652a04fd278a2d82a454b829b42888d2eed22ce Mon Sep 17 00:00:00 2001 From: maliming Date: Tue, 30 Nov 2021 11:48:07 +0800 Subject: [PATCH 3/3] Use `catch (Exception e) when`. --- .../UnitOfWorkDbContextProvider.cs | 98 ++++++------------- 1 file changed, 30 insertions(+), 68 deletions(-) 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 245c3a3d70..535be1192c 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 @@ -187,17 +187,12 @@ namespace Volo.Abp.Uow.EntityFrameworkCore ) ); } - catch (Exception e) + catch (Exception e) when (e is InvalidOperationException || e is NotSupportedException) { - if (e is InvalidOperationException || e is NotSupportedException) - { - Logger.LogError(TransactionsNotSupportedErrorMessage); - Logger.LogException(e); - } - else - { - throw; - } + Logger.LogError(TransactionsNotSupportedErrorMessage); + Logger.LogException(e); + + return dbContext; } return dbContext; @@ -230,19 +225,12 @@ namespace Volo.Abp.Uow.EntityFrameworkCore dbContext.Database.BeginTransaction(); } } - catch (Exception e) + catch (Exception e) when (e is InvalidOperationException || e is NotSupportedException) { - if (e is InvalidOperationException || e is NotSupportedException) - { - Logger.LogError(TransactionsNotSupportedErrorMessage); - Logger.LogException(e); - - return dbContext; - } - else - { - throw; - } + Logger.LogError(TransactionsNotSupportedErrorMessage); + Logger.LogException(e); + + return dbContext; } } } @@ -255,19 +243,12 @@ namespace Volo.Abp.Uow.EntityFrameworkCore */ dbContext.Database.BeginTransaction(); } - catch (Exception e) + catch (Exception e) when (e is InvalidOperationException || e is NotSupportedException) { - if (e is InvalidOperationException || e is NotSupportedException) - { - Logger.LogError(TransactionsNotSupportedErrorMessage); - Logger.LogException(e); - - return dbContext; - } - else - { - throw; - } + Logger.LogError(TransactionsNotSupportedErrorMessage); + Logger.LogException(e); + + return dbContext; } } @@ -301,17 +282,12 @@ namespace Volo.Abp.Uow.EntityFrameworkCore ) ); } - catch (Exception e) + catch (Exception e) when (e is InvalidOperationException || e is NotSupportedException) { - if (e is InvalidOperationException || e is NotSupportedException) - { - Logger.LogError(TransactionsNotSupportedErrorMessage); - Logger.LogException(e); - } - else - { - throw; - } + Logger.LogError(TransactionsNotSupportedErrorMessage); + Logger.LogException(e); + + return dbContext; } return dbContext; @@ -349,19 +325,12 @@ namespace Volo.Abp.Uow.EntityFrameworkCore ); } } - catch (Exception e) + catch (Exception e) when (e is InvalidOperationException || e is NotSupportedException) { - if (e is InvalidOperationException || e is NotSupportedException) - { - Logger.LogError(TransactionsNotSupportedErrorMessage); - Logger.LogException(e); - - return dbContext; - } - else - { - throw; - } + Logger.LogError(TransactionsNotSupportedErrorMessage); + Logger.LogException(e); + + return dbContext; } } } @@ -374,19 +343,12 @@ namespace Volo.Abp.Uow.EntityFrameworkCore */ await dbContext.Database.BeginTransactionAsync(GetCancellationToken()); } - catch (Exception e) + catch (Exception e) when (e is InvalidOperationException || e is NotSupportedException) { - if (e is InvalidOperationException || e is NotSupportedException) - { - Logger.LogError(TransactionsNotSupportedErrorMessage); - Logger.LogException(e); - - return dbContext; - } - else - { - throw; - } + Logger.LogError(TransactionsNotSupportedErrorMessage); + Logger.LogException(e); + + return dbContext; } }