From 59c108f260d1010f46ff18e434fe6adcf1f8d98e Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Mon, 29 Aug 2022 01:45:23 +0000 Subject: [PATCH 01/30] Generate Async Code of .NET Standard 2.1 --- src/AsyncGenerator.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AsyncGenerator.yml b/src/AsyncGenerator.yml index 1f763ac1df9..1ba9d8f10e8 100644 --- a/src/AsyncGenerator.yml +++ b/src/AsyncGenerator.yml @@ -1,6 +1,6 @@ projects: - filePath: NHibernate/NHibernate.csproj - targetFramework: netcoreapp2.0 + targetFramework: netstandard2.1 concurrentRun: true applyChanges: true suppressDiagnosticFailures: From 38ae9900ece2dcb1324f842f0ac8183a68a10f20 Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Mon, 29 Aug 2022 01:59:17 +0000 Subject: [PATCH 02/30] Add shim for DbConnection.BeginTransactionAsync --- src/NHibernate/AdoNet/AsynExtensions.cs | 41 +++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/NHibernate/AdoNet/AsynExtensions.cs diff --git a/src/NHibernate/AdoNet/AsynExtensions.cs b/src/NHibernate/AdoNet/AsynExtensions.cs new file mode 100644 index 00000000000..b2352eab580 --- /dev/null +++ b/src/NHibernate/AdoNet/AsynExtensions.cs @@ -0,0 +1,41 @@ +#if NETFX || NETSTANDARD2_0 || NETCOREAPP2_0 +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace System.Data.Common +{ + internal static class AsyncExtensions + { + public static Task BeginTransactionAsync(this DbConnection connection, CancellationToken cancellationToken = default) + { + if (cancellationToken.IsCancellationRequested) + return Task.FromCanceled(cancellationToken); + + try + { + return Task.FromResult(connection.BeginTransaction()); + } + catch (Exception ex) + { + return Task.FromException(ex); + } + } + + public static Task BeginTransactionAsync(this DbConnection connection, IsolationLevel isolationLevel, CancellationToken cancellationToken = default) + { + if (cancellationToken.IsCancellationRequested) + return Task.FromCanceled(cancellationToken); + + try + { + return Task.FromResult(connection.BeginTransaction(isolationLevel)); + } + catch (Exception ex) + { + return Task.FromException(ex); + } + } + } +} +#endif From 8b483e886b2af52313a65154d414ddbd85181f07 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 29 Aug 2022 02:01:55 +0000 Subject: [PATCH 03/30] Generate async files --- .../Async/NHSpecificTest/GH1547/Fixture.cs | 5 ++ .../TypesTest/AbstractDateTimeTypeFixture.cs | 16 ++++++ .../TypesTest/AbstractDateTimeTypeFixture.cs | 2 +- src/NHibernate/AdoNet/ResultSetWrapper.cs | 2 +- .../Async/AdoNet/AbstractBatcher.cs | 2 +- .../Async/AdoNet/DbCommandWrapper.cs | 10 ++++ .../Async/AdoNet/HanaBatchingBatcher.cs | 2 +- .../Async/AdoNet/ResultSetWrapper.cs | 28 +++++++++ .../Dialect/Lock/SelectLockingStrategy.cs | 3 +- .../Async/Driver/BasicResultSetsCommand.cs | 13 +++++ src/NHibernate/Async/Driver/DriverBase.cs | 57 +++++++++++++++++++ src/NHibernate/Async/Driver/IDriver.cs | 34 +++++++++++ src/NHibernate/Async/Driver/NDataReader.cs | 17 +++++- .../Async/Driver/NHybridDataReader.cs | 6 ++ .../Async/Id/Enhanced/SequenceStructure.cs | 4 +- src/NHibernate/Async/Id/IncrementGenerator.cs | 3 +- .../Async/Id/NativeGuidGenerator.cs | 3 +- src/NHibernate/Async/Id/SequenceGenerator.cs | 3 +- src/NHibernate/Async/Id/TableGenerator.cs | 3 +- .../Entity/AbstractEntityPersister.cs | 7 ++- .../Transaction/AdoNetTransactionFactory.cs | 4 +- .../Async/Transaction/AdoTransaction.cs | 5 +- src/NHibernate/Driver/DriverBase.cs | 2 +- src/NHibernate/Driver/IDriver.cs | 2 +- 24 files changed, 215 insertions(+), 18 deletions(-) create mode 100644 src/NHibernate/Async/AdoNet/ResultSetWrapper.cs create mode 100644 src/NHibernate/Async/Driver/DriverBase.cs create mode 100644 src/NHibernate/Async/Driver/IDriver.cs diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH1547/Fixture.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH1547/Fixture.cs index a9b6818c04f..e66c7c25b12 100644 --- a/src/NHibernate.Test/Async/NHSpecificTest/GH1547/Fixture.cs +++ b/src/NHibernate.Test/Async/NHSpecificTest/GH1547/Fixture.cs @@ -151,6 +151,11 @@ public partial class DriverForSubstitutedCommand : IDriver #endregion #region Pure forwarding + Task IDriver.PrepareCommandAsync(DbCommand command, CancellationToken cancellationToken) + { + return _driverImplementation.PrepareCommandAsync(command, cancellationToken); + } + #endregion private partial class SubstituteDbCommand : DbCommand diff --git a/src/NHibernate.Test/Async/TypesTest/AbstractDateTimeTypeFixture.cs b/src/NHibernate.Test/Async/TypesTest/AbstractDateTimeTypeFixture.cs index 4588e8d1017..8674934f466 100644 --- a/src/NHibernate.Test/Async/TypesTest/AbstractDateTimeTypeFixture.cs +++ b/src/NHibernate.Test/Async/TypesTest/AbstractDateTimeTypeFixture.cs @@ -493,4 +493,20 @@ protected DateTimeKind GetTypeKind() return (DateTimeKind) _kindProperty.GetValue(Type); } } + + public partial class ClientDriverWithParamsStats : IDriver + { + + #region Firebird mess + + #endregion + #region Pure forwarding + + Task IDriver.PrepareCommandAsync(DbCommand command, CancellationToken cancellationToken) + { + return _driverImplementation.PrepareCommandAsync(command, cancellationToken); + } + + #endregion + } } diff --git a/src/NHibernate.Test/TypesTest/AbstractDateTimeTypeFixture.cs b/src/NHibernate.Test/TypesTest/AbstractDateTimeTypeFixture.cs index 67b36a0d2cc..042b3a96378 100644 --- a/src/NHibernate.Test/TypesTest/AbstractDateTimeTypeFixture.cs +++ b/src/NHibernate.Test/TypesTest/AbstractDateTimeTypeFixture.cs @@ -548,7 +548,7 @@ protected DateTimeKind GetTypeKind() } } - public class ClientDriverWithParamsStats : IDriver + public partial class ClientDriverWithParamsStats : IDriver { private readonly Dictionary _usedSqlTypes = new Dictionary(); private readonly Dictionary _usedDbTypes = new Dictionary(); diff --git a/src/NHibernate/AdoNet/ResultSetWrapper.cs b/src/NHibernate/AdoNet/ResultSetWrapper.cs index c801723e499..b6014a01b89 100644 --- a/src/NHibernate/AdoNet/ResultSetWrapper.cs +++ b/src/NHibernate/AdoNet/ResultSetWrapper.cs @@ -13,7 +13,7 @@ namespace NHibernate.AdoNet /// and Postgres). /// /// - public class ResultSetWrapper : DbDataReader + public partial class ResultSetWrapper : DbDataReader { private DbDataReader rs; private readonly ColumnNameCache columnNameCache; diff --git a/src/NHibernate/Async/AdoNet/AbstractBatcher.cs b/src/NHibernate/Async/AdoNet/AbstractBatcher.cs index ed60b6c704c..b0ba6e6c579 100644 --- a/src/NHibernate/Async/AdoNet/AbstractBatcher.cs +++ b/src/NHibernate/Async/AdoNet/AbstractBatcher.cs @@ -59,7 +59,7 @@ protected async Task PrepareAsync(DbCommand cmd, CancellationToken cancellationT } _connectionManager.EnlistInTransaction(cmd); - Driver.PrepareCommand(cmd); + await (Driver.PrepareCommandAsync(cmd, cancellationToken)).ConfigureAwait(false); } catch (InvalidOperationException ioe) { diff --git a/src/NHibernate/Async/AdoNet/DbCommandWrapper.cs b/src/NHibernate/Async/AdoNet/DbCommandWrapper.cs index 3c5da708a4c..671bb35abb0 100644 --- a/src/NHibernate/Async/AdoNet/DbCommandWrapper.cs +++ b/src/NHibernate/Async/AdoNet/DbCommandWrapper.cs @@ -38,6 +38,16 @@ public override Task ExecuteScalarAsync(CancellationToken cancellationTo return Command.ExecuteScalarAsync(cancellationToken); } + /// + public override Task PrepareAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + if (cancellationToken.IsCancellationRequested) + { + return Task.FromCanceled(cancellationToken); + } + return Command.PrepareAsync(cancellationToken); + } + /// protected override Task ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken) { diff --git a/src/NHibernate/Async/AdoNet/HanaBatchingBatcher.cs b/src/NHibernate/Async/AdoNet/HanaBatchingBatcher.cs index e0c06220f52..a8480be1a02 100644 --- a/src/NHibernate/Async/AdoNet/HanaBatchingBatcher.cs +++ b/src/NHibernate/Async/AdoNet/HanaBatchingBatcher.cs @@ -105,7 +105,7 @@ protected override async Task DoExecuteBatchAsync(DbCommand ps, CancellationToke } } - _currentBatch.Prepare(); + await (_currentBatch.PrepareAsync(cancellationToken)).ConfigureAwait(false); try { diff --git a/src/NHibernate/Async/AdoNet/ResultSetWrapper.cs b/src/NHibernate/Async/AdoNet/ResultSetWrapper.cs new file mode 100644 index 00000000000..b5e19ca39a6 --- /dev/null +++ b/src/NHibernate/Async/AdoNet/ResultSetWrapper.cs @@ -0,0 +1,28 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by AsyncGenerator. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + + +using System; +using System.Collections; +using System.Data; +using System.Data.Common; +using System.Threading; +using System.Threading.Tasks; + +namespace NHibernate.AdoNet +{ + public partial class ResultSetWrapper : DbDataReader + { + + public override Task CloseAsync() + { + return rs.CloseAsync(); + } + } +} diff --git a/src/NHibernate/Async/Dialect/Lock/SelectLockingStrategy.cs b/src/NHibernate/Async/Dialect/Lock/SelectLockingStrategy.cs index 1aaf3f93250..537ec584abb 100644 --- a/src/NHibernate/Async/Dialect/Lock/SelectLockingStrategy.cs +++ b/src/NHibernate/Async/Dialect/Lock/SelectLockingStrategy.cs @@ -56,7 +56,8 @@ public async Task LockAsync(object id, object version, object obj, ISessionImple } finally { - rs.Close(); + cancellationToken.ThrowIfCancellationRequested(); + await (rs.CloseAsync()).ConfigureAwait(false); } } finally diff --git a/src/NHibernate/Async/Driver/BasicResultSetsCommand.cs b/src/NHibernate/Async/Driver/BasicResultSetsCommand.cs index 83560a9bfd0..c75321cf594 100644 --- a/src/NHibernate/Async/Driver/BasicResultSetsCommand.cs +++ b/src/NHibernate/Async/Driver/BasicResultSetsCommand.cs @@ -53,5 +53,18 @@ public static async Task CreateAsync(IBatcher batcher, reader = await (batcher.ExecuteReaderAsync(command, cancellationToken)).ConfigureAwait(false) }; } + + public override Task CloseAsync() + { + try + { + Close(); + return Task.CompletedTask; + } + catch (Exception ex) + { + return Task.FromException(ex); + } + } } } diff --git a/src/NHibernate/Async/Driver/DriverBase.cs b/src/NHibernate/Async/Driver/DriverBase.cs new file mode 100644 index 00000000000..9aaa8c999a9 --- /dev/null +++ b/src/NHibernate/Async/Driver/DriverBase.cs @@ -0,0 +1,57 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by AsyncGenerator. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + + +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using NHibernate.Engine; +using NHibernate.SqlCommand; +using NHibernate.SqlTypes; +using NHibernate.Util; +using Environment = NHibernate.Cfg.Environment; + +namespace NHibernate.Driver +{ + using System.Threading.Tasks; + using System.Threading; + public abstract partial class DriverBase : IDriver, ISqlParameterFormatter + { + + public Task PrepareCommandAsync(DbCommand command, CancellationToken cancellationToken) + { + if (cancellationToken.IsCancellationRequested) + { + return Task.FromCanceled(cancellationToken); + } + try + { + AdjustCommand(command); + OnBeforePrepare(command); + + if (SupportsPreparingCommands && prepareSql) + { + return command.PrepareAsync(cancellationToken); + } + return Task.CompletedTask; + } + catch (Exception ex) + { + return Task.FromException(ex); + } + } + + #if NETFX + #else + + #endif + } +} diff --git a/src/NHibernate/Async/Driver/IDriver.cs b/src/NHibernate/Async/Driver/IDriver.cs new file mode 100644 index 00000000000..1c37e23f6f4 --- /dev/null +++ b/src/NHibernate/Async/Driver/IDriver.cs @@ -0,0 +1,34 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by AsyncGenerator. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + + +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using NHibernate.Engine; +using NHibernate.SqlCommand; +using NHibernate.SqlTypes; + +namespace NHibernate.Driver +{ + using System.Threading.Tasks; + using System.Threading; + public partial interface IDriver + { + + /// + /// Prepare the by calling . + /// May be a no-op if the driver does not support preparing commands, or for any other reason. + /// + /// The command. + /// A cancellation token that can be used to cancel the work + Task PrepareCommandAsync(DbCommand command, CancellationToken cancellationToken); + } +} diff --git a/src/NHibernate/Async/Driver/NDataReader.cs b/src/NHibernate/Async/Driver/NDataReader.cs index 124756c15b8..085bcb7b6b5 100644 --- a/src/NHibernate/Async/Driver/NDataReader.cs +++ b/src/NHibernate/Async/Driver/NDataReader.cs @@ -67,11 +67,26 @@ public static async Task CreateAsync(DbDataReader reader, bool isMi } finally { - reader.Close(); + cancellationToken.ThrowIfCancellationRequested(); + await (reader.CloseAsync()).ConfigureAwait(false); } return dataReader; } + /// + public override Task CloseAsync() + { + try + { + Close(); + return Task.CompletedTask; + } + catch (Exception ex) + { + return Task.FromException(ex); + } + } + private partial class NResult { diff --git a/src/NHibernate/Async/Driver/NHybridDataReader.cs b/src/NHibernate/Async/Driver/NHybridDataReader.cs index 1706b3913a8..6034cbdc236 100644 --- a/src/NHibernate/Async/Driver/NHybridDataReader.cs +++ b/src/NHibernate/Async/Driver/NHybridDataReader.cs @@ -75,5 +75,11 @@ public async Task ReadIntoMemoryAsync(CancellationToken cancellationToken) _reader = await (NDataReader.CreateAsync(_reader, _isMidstream, cancellationToken)).ConfigureAwait(false); } } + + /// + public override Task CloseAsync() + { + return _reader.CloseAsync(); + } } } diff --git a/src/NHibernate/Async/Id/Enhanced/SequenceStructure.cs b/src/NHibernate/Async/Id/Enhanced/SequenceStructure.cs index a3a7fd57d54..88d17e0751c 100644 --- a/src/NHibernate/Async/Id/Enhanced/SequenceStructure.cs +++ b/src/NHibernate/Async/Id/Enhanced/SequenceStructure.cs @@ -56,8 +56,10 @@ public virtual async Task GetNextValueAsync(CancellationToken cancellation { try { - rs.Close(); + cancellationToken.ThrowIfCancellationRequested(); + await (rs.CloseAsync()).ConfigureAwait(false); } + catch (OperationCanceledException) { throw; } catch { // intentionally empty diff --git a/src/NHibernate/Async/Id/IncrementGenerator.cs b/src/NHibernate/Async/Id/IncrementGenerator.cs index 4df097d6624..3c158826e08 100644 --- a/src/NHibernate/Async/Id/IncrementGenerator.cs +++ b/src/NHibernate/Async/Id/IncrementGenerator.cs @@ -76,7 +76,8 @@ private async Task GetNextAsync(ISessionImplementor session, CancellationToken c } finally { - reader.Close(); + cancellationToken.ThrowIfCancellationRequested(); + await (reader.CloseAsync()).ConfigureAwait(false); } } finally diff --git a/src/NHibernate/Async/Id/NativeGuidGenerator.cs b/src/NHibernate/Async/Id/NativeGuidGenerator.cs index 29e20e4ffbd..ead38e4cc00 100644 --- a/src/NHibernate/Async/Id/NativeGuidGenerator.cs +++ b/src/NHibernate/Async/Id/NativeGuidGenerator.cs @@ -46,7 +46,8 @@ public async Task GenerateAsync(ISessionImplementor session, object obj, } finally { - reader.Close(); + cancellationToken.ThrowIfCancellationRequested(); + await (reader.CloseAsync()).ConfigureAwait(false); } log.Debug("GUID identifier generated: {0}", result); return result; diff --git a/src/NHibernate/Async/Id/SequenceGenerator.cs b/src/NHibernate/Async/Id/SequenceGenerator.cs index 5cb811a7e45..a2db7edb905 100644 --- a/src/NHibernate/Async/Id/SequenceGenerator.cs +++ b/src/NHibernate/Async/Id/SequenceGenerator.cs @@ -60,7 +60,8 @@ public virtual async Task GenerateAsync(ISessionImplementor session, obj } finally { - reader.Close(); + cancellationToken.ThrowIfCancellationRequested(); + await (reader.CloseAsync()).ConfigureAwait(false); } } finally diff --git a/src/NHibernate/Async/Id/TableGenerator.cs b/src/NHibernate/Async/Id/TableGenerator.cs index 3ad468a09be..ad59fc771b9 100644 --- a/src/NHibernate/Async/Id/TableGenerator.cs +++ b/src/NHibernate/Async/Id/TableGenerator.cs @@ -95,7 +95,8 @@ public override async Task DoWorkInCurrentTransactionAsync(ISessionImple { if (rs != null) { - rs.Close(); + cancellationToken.ThrowIfCancellationRequested(); + await (rs.CloseAsync()).ConfigureAwait(false); } qps.Dispose(); } diff --git a/src/NHibernate/Async/Persister/Entity/AbstractEntityPersister.cs b/src/NHibernate/Async/Persister/Entity/AbstractEntityPersister.cs index d5005ea10af..88dd780c6f1 100644 --- a/src/NHibernate/Async/Persister/Entity/AbstractEntityPersister.cs +++ b/src/NHibernate/Async/Persister/Entity/AbstractEntityPersister.cs @@ -525,7 +525,12 @@ private async Task HydrateAsync(DbDataReader rs, object id, object obj } finally { - sequentialResultSet?.Close(); + cancellationToken.ThrowIfCancellationRequested(); + var closeTask = sequentialResultSet?.CloseAsync(); + if (closeTask != null) + { + await (closeTask).ConfigureAwait(false); + } if (sequentialSelect != null) { session.Batcher.CloseCommand(sequentialSelect, sequentialResultSet); diff --git a/src/NHibernate/Async/Transaction/AdoNetTransactionFactory.cs b/src/NHibernate/Async/Transaction/AdoNetTransactionFactory.cs index 2fd5c3fa458..14163432ce4 100644 --- a/src/NHibernate/Async/Transaction/AdoNetTransactionFactory.cs +++ b/src/NHibernate/Async/Transaction/AdoNetTransactionFactory.cs @@ -58,7 +58,7 @@ async Task InternalExecuteWorkInIsolationAsync() if (transacted) { - trans.Commit(); + await (trans.CommitAsync(cancellationToken)).ConfigureAwait(false); } } catch (Exception t) @@ -69,7 +69,7 @@ async Task InternalExecuteWorkInIsolationAsync() { if (trans != null && connection.State != ConnectionState.Closed) { - trans.Rollback(); + await (trans.RollbackAsync(cancellationToken)).ConfigureAwait(false); } } catch (Exception ignore) diff --git a/src/NHibernate/Async/Transaction/AdoTransaction.cs b/src/NHibernate/Async/Transaction/AdoTransaction.cs index a8b249130fa..64137399251 100644 --- a/src/NHibernate/Async/Transaction/AdoTransaction.cs +++ b/src/NHibernate/Async/Transaction/AdoTransaction.cs @@ -63,7 +63,7 @@ private async Task AfterTransactionCompletionAsync(bool successful, Cancellation try { - trans.Commit(); + await (trans.CommitAsync(cancellationToken)).ConfigureAwait(false); log.Debug("DbTransaction Committed"); committed = true; @@ -117,11 +117,12 @@ private async Task AfterTransactionCompletionAsync(bool successful, Cancellation { try { - trans.Rollback(); + await (trans.RollbackAsync(cancellationToken)).ConfigureAwait(false); log.Debug("DbTransaction RolledBack"); rolledBack = true; Dispose(); } + catch (OperationCanceledException) { throw; } catch (HibernateException e) { log.Error(e, "Rollback failed"); diff --git a/src/NHibernate/Driver/DriverBase.cs b/src/NHibernate/Driver/DriverBase.cs index be5c81366e1..9e18bdf0255 100644 --- a/src/NHibernate/Driver/DriverBase.cs +++ b/src/NHibernate/Driver/DriverBase.cs @@ -14,7 +14,7 @@ namespace NHibernate.Driver /// /// Base class for the implementation of IDriver /// - public abstract class DriverBase : IDriver, ISqlParameterFormatter + public abstract partial class DriverBase : IDriver, ISqlParameterFormatter { private static readonly INHibernateLogger log = NHibernateLogger.For(typeof(DriverBase)); diff --git a/src/NHibernate/Driver/IDriver.cs b/src/NHibernate/Driver/IDriver.cs index 61e40b64213..71ae3c0a10d 100644 --- a/src/NHibernate/Driver/IDriver.cs +++ b/src/NHibernate/Driver/IDriver.cs @@ -30,7 +30,7 @@ namespace NHibernate.Driver /// value="FullyQualifiedClassName, AssemblyName" /// /// - public interface IDriver + public partial interface IDriver { /// /// Configure the driver using . From 691e9676ba56b98da1a46566f7ac3c2961d7b293 Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Mon, 29 Aug 2022 02:10:08 +0000 Subject: [PATCH 04/30] Update AsyncGenerator.yml --- src/AsyncGenerator.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AsyncGenerator.yml b/src/AsyncGenerator.yml index 1ba9d8f10e8..1f763ac1df9 100644 --- a/src/AsyncGenerator.yml +++ b/src/AsyncGenerator.yml @@ -1,6 +1,6 @@ projects: - filePath: NHibernate/NHibernate.csproj - targetFramework: netstandard2.1 + targetFramework: netcoreapp2.0 concurrentRun: true applyChanges: true suppressDiagnosticFailures: From e1968806acb172623de6e2c4571ac7408012ea75 Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Mon, 29 Aug 2022 02:10:36 +0000 Subject: [PATCH 05/30] Rename AsynExtensions.cs to AsyncExtensions.cs --- src/NHibernate/AdoNet/{AsynExtensions.cs => AsyncExtensions.cs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/NHibernate/AdoNet/{AsynExtensions.cs => AsyncExtensions.cs} (100%) diff --git a/src/NHibernate/AdoNet/AsynExtensions.cs b/src/NHibernate/AdoNet/AsyncExtensions.cs similarity index 100% rename from src/NHibernate/AdoNet/AsynExtensions.cs rename to src/NHibernate/AdoNet/AsyncExtensions.cs From 685267a33272c797fa135b8667651544bb5b5a72 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 29 Aug 2022 02:13:54 +0000 Subject: [PATCH 06/30] Generate async files --- .../Async/NHSpecificTest/GH1547/Fixture.cs | 5 -- .../TypesTest/AbstractDateTimeTypeFixture.cs | 16 ------ .../Async/AdoNet/AbstractBatcher.cs | 2 +- .../Async/AdoNet/DbCommandWrapper.cs | 10 ---- .../Async/AdoNet/HanaBatchingBatcher.cs | 2 +- .../Async/AdoNet/ResultSetWrapper.cs | 28 --------- .../Dialect/Lock/SelectLockingStrategy.cs | 3 +- .../Async/Driver/BasicResultSetsCommand.cs | 13 ----- src/NHibernate/Async/Driver/DriverBase.cs | 57 ------------------- src/NHibernate/Async/Driver/IDriver.cs | 34 ----------- src/NHibernate/Async/Driver/NDataReader.cs | 17 +----- .../Async/Driver/NHybridDataReader.cs | 6 -- .../Async/Id/Enhanced/SequenceStructure.cs | 4 +- src/NHibernate/Async/Id/IncrementGenerator.cs | 3 +- .../Async/Id/NativeGuidGenerator.cs | 3 +- src/NHibernate/Async/Id/SequenceGenerator.cs | 3 +- src/NHibernate/Async/Id/TableGenerator.cs | 3 +- .../Entity/AbstractEntityPersister.cs | 7 +-- .../Transaction/AdoNetTransactionFactory.cs | 4 +- .../Async/Transaction/AdoTransaction.cs | 5 +- 20 files changed, 14 insertions(+), 211 deletions(-) delete mode 100644 src/NHibernate/Async/AdoNet/ResultSetWrapper.cs delete mode 100644 src/NHibernate/Async/Driver/DriverBase.cs delete mode 100644 src/NHibernate/Async/Driver/IDriver.cs diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH1547/Fixture.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH1547/Fixture.cs index e66c7c25b12..a9b6818c04f 100644 --- a/src/NHibernate.Test/Async/NHSpecificTest/GH1547/Fixture.cs +++ b/src/NHibernate.Test/Async/NHSpecificTest/GH1547/Fixture.cs @@ -151,11 +151,6 @@ public partial class DriverForSubstitutedCommand : IDriver #endregion #region Pure forwarding - Task IDriver.PrepareCommandAsync(DbCommand command, CancellationToken cancellationToken) - { - return _driverImplementation.PrepareCommandAsync(command, cancellationToken); - } - #endregion private partial class SubstituteDbCommand : DbCommand diff --git a/src/NHibernate.Test/Async/TypesTest/AbstractDateTimeTypeFixture.cs b/src/NHibernate.Test/Async/TypesTest/AbstractDateTimeTypeFixture.cs index 8674934f466..4588e8d1017 100644 --- a/src/NHibernate.Test/Async/TypesTest/AbstractDateTimeTypeFixture.cs +++ b/src/NHibernate.Test/Async/TypesTest/AbstractDateTimeTypeFixture.cs @@ -493,20 +493,4 @@ protected DateTimeKind GetTypeKind() return (DateTimeKind) _kindProperty.GetValue(Type); } } - - public partial class ClientDriverWithParamsStats : IDriver - { - - #region Firebird mess - - #endregion - #region Pure forwarding - - Task IDriver.PrepareCommandAsync(DbCommand command, CancellationToken cancellationToken) - { - return _driverImplementation.PrepareCommandAsync(command, cancellationToken); - } - - #endregion - } } diff --git a/src/NHibernate/Async/AdoNet/AbstractBatcher.cs b/src/NHibernate/Async/AdoNet/AbstractBatcher.cs index b0ba6e6c579..ed60b6c704c 100644 --- a/src/NHibernate/Async/AdoNet/AbstractBatcher.cs +++ b/src/NHibernate/Async/AdoNet/AbstractBatcher.cs @@ -59,7 +59,7 @@ protected async Task PrepareAsync(DbCommand cmd, CancellationToken cancellationT } _connectionManager.EnlistInTransaction(cmd); - await (Driver.PrepareCommandAsync(cmd, cancellationToken)).ConfigureAwait(false); + Driver.PrepareCommand(cmd); } catch (InvalidOperationException ioe) { diff --git a/src/NHibernate/Async/AdoNet/DbCommandWrapper.cs b/src/NHibernate/Async/AdoNet/DbCommandWrapper.cs index 671bb35abb0..3c5da708a4c 100644 --- a/src/NHibernate/Async/AdoNet/DbCommandWrapper.cs +++ b/src/NHibernate/Async/AdoNet/DbCommandWrapper.cs @@ -38,16 +38,6 @@ public override Task ExecuteScalarAsync(CancellationToken cancellationTo return Command.ExecuteScalarAsync(cancellationToken); } - /// - public override Task PrepareAsync(CancellationToken cancellationToken = default(CancellationToken)) - { - if (cancellationToken.IsCancellationRequested) - { - return Task.FromCanceled(cancellationToken); - } - return Command.PrepareAsync(cancellationToken); - } - /// protected override Task ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken) { diff --git a/src/NHibernate/Async/AdoNet/HanaBatchingBatcher.cs b/src/NHibernate/Async/AdoNet/HanaBatchingBatcher.cs index a8480be1a02..e0c06220f52 100644 --- a/src/NHibernate/Async/AdoNet/HanaBatchingBatcher.cs +++ b/src/NHibernate/Async/AdoNet/HanaBatchingBatcher.cs @@ -105,7 +105,7 @@ protected override async Task DoExecuteBatchAsync(DbCommand ps, CancellationToke } } - await (_currentBatch.PrepareAsync(cancellationToken)).ConfigureAwait(false); + _currentBatch.Prepare(); try { diff --git a/src/NHibernate/Async/AdoNet/ResultSetWrapper.cs b/src/NHibernate/Async/AdoNet/ResultSetWrapper.cs deleted file mode 100644 index b5e19ca39a6..00000000000 --- a/src/NHibernate/Async/AdoNet/ResultSetWrapper.cs +++ /dev/null @@ -1,28 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by AsyncGenerator. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - - -using System; -using System.Collections; -using System.Data; -using System.Data.Common; -using System.Threading; -using System.Threading.Tasks; - -namespace NHibernate.AdoNet -{ - public partial class ResultSetWrapper : DbDataReader - { - - public override Task CloseAsync() - { - return rs.CloseAsync(); - } - } -} diff --git a/src/NHibernate/Async/Dialect/Lock/SelectLockingStrategy.cs b/src/NHibernate/Async/Dialect/Lock/SelectLockingStrategy.cs index 537ec584abb..1aaf3f93250 100644 --- a/src/NHibernate/Async/Dialect/Lock/SelectLockingStrategy.cs +++ b/src/NHibernate/Async/Dialect/Lock/SelectLockingStrategy.cs @@ -56,8 +56,7 @@ public async Task LockAsync(object id, object version, object obj, ISessionImple } finally { - cancellationToken.ThrowIfCancellationRequested(); - await (rs.CloseAsync()).ConfigureAwait(false); + rs.Close(); } } finally diff --git a/src/NHibernate/Async/Driver/BasicResultSetsCommand.cs b/src/NHibernate/Async/Driver/BasicResultSetsCommand.cs index c75321cf594..83560a9bfd0 100644 --- a/src/NHibernate/Async/Driver/BasicResultSetsCommand.cs +++ b/src/NHibernate/Async/Driver/BasicResultSetsCommand.cs @@ -53,18 +53,5 @@ public static async Task CreateAsync(IBatcher batcher, reader = await (batcher.ExecuteReaderAsync(command, cancellationToken)).ConfigureAwait(false) }; } - - public override Task CloseAsync() - { - try - { - Close(); - return Task.CompletedTask; - } - catch (Exception ex) - { - return Task.FromException(ex); - } - } } } diff --git a/src/NHibernate/Async/Driver/DriverBase.cs b/src/NHibernate/Async/Driver/DriverBase.cs deleted file mode 100644 index 9aaa8c999a9..00000000000 --- a/src/NHibernate/Async/Driver/DriverBase.cs +++ /dev/null @@ -1,57 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by AsyncGenerator. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - - -using System; -using System.Collections.Generic; -using System.Data; -using System.Data.Common; -using System.Linq; -using NHibernate.Engine; -using NHibernate.SqlCommand; -using NHibernate.SqlTypes; -using NHibernate.Util; -using Environment = NHibernate.Cfg.Environment; - -namespace NHibernate.Driver -{ - using System.Threading.Tasks; - using System.Threading; - public abstract partial class DriverBase : IDriver, ISqlParameterFormatter - { - - public Task PrepareCommandAsync(DbCommand command, CancellationToken cancellationToken) - { - if (cancellationToken.IsCancellationRequested) - { - return Task.FromCanceled(cancellationToken); - } - try - { - AdjustCommand(command); - OnBeforePrepare(command); - - if (SupportsPreparingCommands && prepareSql) - { - return command.PrepareAsync(cancellationToken); - } - return Task.CompletedTask; - } - catch (Exception ex) - { - return Task.FromException(ex); - } - } - - #if NETFX - #else - - #endif - } -} diff --git a/src/NHibernate/Async/Driver/IDriver.cs b/src/NHibernate/Async/Driver/IDriver.cs deleted file mode 100644 index 1c37e23f6f4..00000000000 --- a/src/NHibernate/Async/Driver/IDriver.cs +++ /dev/null @@ -1,34 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by AsyncGenerator. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - - -using System; -using System.Collections.Generic; -using System.Data; -using System.Data.Common; -using NHibernate.Engine; -using NHibernate.SqlCommand; -using NHibernate.SqlTypes; - -namespace NHibernate.Driver -{ - using System.Threading.Tasks; - using System.Threading; - public partial interface IDriver - { - - /// - /// Prepare the by calling . - /// May be a no-op if the driver does not support preparing commands, or for any other reason. - /// - /// The command. - /// A cancellation token that can be used to cancel the work - Task PrepareCommandAsync(DbCommand command, CancellationToken cancellationToken); - } -} diff --git a/src/NHibernate/Async/Driver/NDataReader.cs b/src/NHibernate/Async/Driver/NDataReader.cs index 085bcb7b6b5..124756c15b8 100644 --- a/src/NHibernate/Async/Driver/NDataReader.cs +++ b/src/NHibernate/Async/Driver/NDataReader.cs @@ -67,26 +67,11 @@ public static async Task CreateAsync(DbDataReader reader, bool isMi } finally { - cancellationToken.ThrowIfCancellationRequested(); - await (reader.CloseAsync()).ConfigureAwait(false); + reader.Close(); } return dataReader; } - /// - public override Task CloseAsync() - { - try - { - Close(); - return Task.CompletedTask; - } - catch (Exception ex) - { - return Task.FromException(ex); - } - } - private partial class NResult { diff --git a/src/NHibernate/Async/Driver/NHybridDataReader.cs b/src/NHibernate/Async/Driver/NHybridDataReader.cs index 6034cbdc236..1706b3913a8 100644 --- a/src/NHibernate/Async/Driver/NHybridDataReader.cs +++ b/src/NHibernate/Async/Driver/NHybridDataReader.cs @@ -75,11 +75,5 @@ public async Task ReadIntoMemoryAsync(CancellationToken cancellationToken) _reader = await (NDataReader.CreateAsync(_reader, _isMidstream, cancellationToken)).ConfigureAwait(false); } } - - /// - public override Task CloseAsync() - { - return _reader.CloseAsync(); - } } } diff --git a/src/NHibernate/Async/Id/Enhanced/SequenceStructure.cs b/src/NHibernate/Async/Id/Enhanced/SequenceStructure.cs index 88d17e0751c..a3a7fd57d54 100644 --- a/src/NHibernate/Async/Id/Enhanced/SequenceStructure.cs +++ b/src/NHibernate/Async/Id/Enhanced/SequenceStructure.cs @@ -56,10 +56,8 @@ public virtual async Task GetNextValueAsync(CancellationToken cancellation { try { - cancellationToken.ThrowIfCancellationRequested(); - await (rs.CloseAsync()).ConfigureAwait(false); + rs.Close(); } - catch (OperationCanceledException) { throw; } catch { // intentionally empty diff --git a/src/NHibernate/Async/Id/IncrementGenerator.cs b/src/NHibernate/Async/Id/IncrementGenerator.cs index 3c158826e08..4df097d6624 100644 --- a/src/NHibernate/Async/Id/IncrementGenerator.cs +++ b/src/NHibernate/Async/Id/IncrementGenerator.cs @@ -76,8 +76,7 @@ private async Task GetNextAsync(ISessionImplementor session, CancellationToken c } finally { - cancellationToken.ThrowIfCancellationRequested(); - await (reader.CloseAsync()).ConfigureAwait(false); + reader.Close(); } } finally diff --git a/src/NHibernate/Async/Id/NativeGuidGenerator.cs b/src/NHibernate/Async/Id/NativeGuidGenerator.cs index ead38e4cc00..29e20e4ffbd 100644 --- a/src/NHibernate/Async/Id/NativeGuidGenerator.cs +++ b/src/NHibernate/Async/Id/NativeGuidGenerator.cs @@ -46,8 +46,7 @@ public async Task GenerateAsync(ISessionImplementor session, object obj, } finally { - cancellationToken.ThrowIfCancellationRequested(); - await (reader.CloseAsync()).ConfigureAwait(false); + reader.Close(); } log.Debug("GUID identifier generated: {0}", result); return result; diff --git a/src/NHibernate/Async/Id/SequenceGenerator.cs b/src/NHibernate/Async/Id/SequenceGenerator.cs index a2db7edb905..5cb811a7e45 100644 --- a/src/NHibernate/Async/Id/SequenceGenerator.cs +++ b/src/NHibernate/Async/Id/SequenceGenerator.cs @@ -60,8 +60,7 @@ public virtual async Task GenerateAsync(ISessionImplementor session, obj } finally { - cancellationToken.ThrowIfCancellationRequested(); - await (reader.CloseAsync()).ConfigureAwait(false); + reader.Close(); } } finally diff --git a/src/NHibernate/Async/Id/TableGenerator.cs b/src/NHibernate/Async/Id/TableGenerator.cs index ad59fc771b9..3ad468a09be 100644 --- a/src/NHibernate/Async/Id/TableGenerator.cs +++ b/src/NHibernate/Async/Id/TableGenerator.cs @@ -95,8 +95,7 @@ public override async Task DoWorkInCurrentTransactionAsync(ISessionImple { if (rs != null) { - cancellationToken.ThrowIfCancellationRequested(); - await (rs.CloseAsync()).ConfigureAwait(false); + rs.Close(); } qps.Dispose(); } diff --git a/src/NHibernate/Async/Persister/Entity/AbstractEntityPersister.cs b/src/NHibernate/Async/Persister/Entity/AbstractEntityPersister.cs index 88dd780c6f1..d5005ea10af 100644 --- a/src/NHibernate/Async/Persister/Entity/AbstractEntityPersister.cs +++ b/src/NHibernate/Async/Persister/Entity/AbstractEntityPersister.cs @@ -525,12 +525,7 @@ private async Task HydrateAsync(DbDataReader rs, object id, object obj } finally { - cancellationToken.ThrowIfCancellationRequested(); - var closeTask = sequentialResultSet?.CloseAsync(); - if (closeTask != null) - { - await (closeTask).ConfigureAwait(false); - } + sequentialResultSet?.Close(); if (sequentialSelect != null) { session.Batcher.CloseCommand(sequentialSelect, sequentialResultSet); diff --git a/src/NHibernate/Async/Transaction/AdoNetTransactionFactory.cs b/src/NHibernate/Async/Transaction/AdoNetTransactionFactory.cs index 14163432ce4..2fd5c3fa458 100644 --- a/src/NHibernate/Async/Transaction/AdoNetTransactionFactory.cs +++ b/src/NHibernate/Async/Transaction/AdoNetTransactionFactory.cs @@ -58,7 +58,7 @@ async Task InternalExecuteWorkInIsolationAsync() if (transacted) { - await (trans.CommitAsync(cancellationToken)).ConfigureAwait(false); + trans.Commit(); } } catch (Exception t) @@ -69,7 +69,7 @@ async Task InternalExecuteWorkInIsolationAsync() { if (trans != null && connection.State != ConnectionState.Closed) { - await (trans.RollbackAsync(cancellationToken)).ConfigureAwait(false); + trans.Rollback(); } } catch (Exception ignore) diff --git a/src/NHibernate/Async/Transaction/AdoTransaction.cs b/src/NHibernate/Async/Transaction/AdoTransaction.cs index 64137399251..a8b249130fa 100644 --- a/src/NHibernate/Async/Transaction/AdoTransaction.cs +++ b/src/NHibernate/Async/Transaction/AdoTransaction.cs @@ -63,7 +63,7 @@ private async Task AfterTransactionCompletionAsync(bool successful, Cancellation try { - await (trans.CommitAsync(cancellationToken)).ConfigureAwait(false); + trans.Commit(); log.Debug("DbTransaction Committed"); committed = true; @@ -117,12 +117,11 @@ private async Task AfterTransactionCompletionAsync(bool successful, Cancellation { try { - await (trans.RollbackAsync(cancellationToken)).ConfigureAwait(false); + trans.Rollback(); log.Debug("DbTransaction RolledBack"); rolledBack = true; Dispose(); } - catch (OperationCanceledException) { throw; } catch (HibernateException e) { log.Error(e, "Rollback failed"); From d4f9e18285bcb3ea8ec066384ece1392cd7a1ff5 Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Thu, 1 Sep 2022 01:02:44 +0000 Subject: [PATCH 07/30] Update AsyncGenerator.yml --- src/AsyncGenerator.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/AsyncGenerator.yml b/src/AsyncGenerator.yml index 1f763ac1df9..93cac87f643 100644 --- a/src/AsyncGenerator.yml +++ b/src/AsyncGenerator.yml @@ -124,6 +124,9 @@ - conversion: ToAsync name: ExecuteNonQuery containingTypeName: IBatcher + - conversion: ToAsync + name: BeginTransaction + containingTypeName: AbstractSessionImpl - conversion: ToAsync rule: EventListener - conversion: ToAsync From 6d46bf6af440c36769b79298474be6e0359e6b66 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 1 Sep 2022 01:05:35 +0000 Subject: [PATCH 08/30] Generate async files --- .../Async/Impl/AbstractSessionImpl.cs | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/NHibernate/Async/Impl/AbstractSessionImpl.cs b/src/NHibernate/Async/Impl/AbstractSessionImpl.cs index ed3948ad38e..9314e14dcbc 100644 --- a/src/NHibernate/Async/Impl/AbstractSessionImpl.cs +++ b/src/NHibernate/Async/Impl/AbstractSessionImpl.cs @@ -212,6 +212,39 @@ protected async Task AfterOperationAsync(bool success, CancellationToken cancell } } + /// + /// Begin a NHibernate transaction + /// + /// A NHibernate transaction + public Task BeginTransactionAsync() + { + try + { + return Task.FromResult(BeginTransaction()); + } + catch (Exception ex) + { + return Task.FromException(ex); + } + } + + /// + /// Begin a NHibernate transaction with the specified isolation level + /// + /// The isolation level + /// A NHibernate transaction + public Task BeginTransactionAsync(IsolationLevel isolationLevel) + { + try + { + return Task.FromResult(BeginTransaction(isolationLevel)); + } + catch (Exception ex) + { + return Task.FromException(ex); + } + } + public abstract Task CreateFilterAsync(object collection, IQueryExpression queryExpression, CancellationToken cancellationToken); public abstract Task EnumerableAsync(IQueryExpression queryExpression, QueryParameters queryParameters, CancellationToken cancellationToken); From de5e2567ee8c5d1afd54123acafa8f2fea4b2e15 Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Thu, 1 Sep 2022 01:06:31 +0000 Subject: [PATCH 09/30] Update AsyncExtensions.cs --- src/NHibernate/AdoNet/AsyncExtensions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NHibernate/AdoNet/AsyncExtensions.cs b/src/NHibernate/AdoNet/AsyncExtensions.cs index b2352eab580..29cc2d83c6f 100644 --- a/src/NHibernate/AdoNet/AsyncExtensions.cs +++ b/src/NHibernate/AdoNet/AsyncExtensions.cs @@ -18,7 +18,7 @@ public static Task BeginTransactionAsync(this DbConnection connec } catch (Exception ex) { - return Task.FromException(ex); + return Task.FromException(ex); } } @@ -33,7 +33,7 @@ public static Task BeginTransactionAsync(this DbConnection connec } catch (Exception ex) { - return Task.FromException(ex); + return Task.FromException(ex); } } } From d5f6eeb062e409017290342b9758ddeb96aa7900 Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Thu, 1 Sep 2022 01:09:20 +0000 Subject: [PATCH 10/30] Update AsyncGenerator.yml --- src/AsyncGenerator.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AsyncGenerator.yml b/src/AsyncGenerator.yml index 93cac87f643..0d01d26e491 100644 --- a/src/AsyncGenerator.yml +++ b/src/AsyncGenerator.yml @@ -126,7 +126,7 @@ containingTypeName: IBatcher - conversion: ToAsync name: BeginTransaction - containingTypeName: AbstractSessionImpl + containingTypeName: ConnectionManager - conversion: ToAsync rule: EventListener - conversion: ToAsync From 85e62a583e80145c5c6d7cb5152aa3c2eff3ddd1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 1 Sep 2022 01:12:40 +0000 Subject: [PATCH 11/30] Generate async files --- .../Async/AdoNet/ConnectionManager.cs | 24 +++++++++++++ .../Async/Impl/AbstractSessionImpl.cs | 34 +++++++++++-------- 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/src/NHibernate/Async/AdoNet/ConnectionManager.cs b/src/NHibernate/Async/AdoNet/ConnectionManager.cs index 4032066ee0a..029b5c7b209 100644 --- a/src/NHibernate/Async/AdoNet/ConnectionManager.cs +++ b/src/NHibernate/Async/AdoNet/ConnectionManager.cs @@ -106,6 +106,30 @@ async Task InternalGetConnectionAsync() } } + public Task BeginTransactionAsync(IsolationLevel isolationLevel) + { + try + { + return Task.FromResult(BeginTransaction(isolationLevel)); + } + catch (Exception ex) + { + return Task.FromException(ex); + } + } + + public Task BeginTransactionAsync() + { + try + { + return Task.FromResult(BeginTransaction()); + } + catch (Exception ex) + { + return Task.FromException(ex); + } + } + public async Task CreateCommandAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); diff --git a/src/NHibernate/Async/Impl/AbstractSessionImpl.cs b/src/NHibernate/Async/Impl/AbstractSessionImpl.cs index 9314e14dcbc..718a0ed72f2 100644 --- a/src/NHibernate/Async/Impl/AbstractSessionImpl.cs +++ b/src/NHibernate/Async/Impl/AbstractSessionImpl.cs @@ -216,15 +216,18 @@ protected async Task AfterOperationAsync(bool success, CancellationToken cancell /// Begin a NHibernate transaction /// /// A NHibernate transaction - public Task BeginTransactionAsync() + public async Task BeginTransactionAsync() { - try - { - return Task.FromResult(BeginTransaction()); - } - catch (Exception ex) + using (BeginProcess()) { - return Task.FromException(ex); + if (IsTransactionCoordinatorShared) + { + // Todo : should seriously consider not allowing a txn to begin from a child session + // can always route the request to the root session... + Log.Warn("Transaction started on non-root session"); + } + + return await (ConnectionManager.BeginTransactionAsync()).ConfigureAwait(false); } } @@ -233,15 +236,18 @@ public Task BeginTransactionAsync() /// /// The isolation level /// A NHibernate transaction - public Task BeginTransactionAsync(IsolationLevel isolationLevel) + public async Task BeginTransactionAsync(IsolationLevel isolationLevel) { - try - { - return Task.FromResult(BeginTransaction(isolationLevel)); - } - catch (Exception ex) + using (BeginProcess()) { - return Task.FromException(ex); + if (IsTransactionCoordinatorShared) + { + // Todo : should seriously consider not allowing a txn to begin from a child session + // can always route the request to the root session... + Log.Warn("Transaction started on non-root session"); + } + + return await (ConnectionManager.BeginTransactionAsync(isolationLevel)).ConfigureAwait(false); } } From 78ffed78e747ea114455e94d27980970a86935df Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Thu, 1 Sep 2022 01:16:34 +0000 Subject: [PATCH 12/30] Update ITransaction.cs --- src/NHibernate/ITransaction.cs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/NHibernate/ITransaction.cs b/src/NHibernate/ITransaction.cs index 9ed0a1dff78..19d4e67788e 100644 --- a/src/NHibernate/ITransaction.cs +++ b/src/NHibernate/ITransaction.cs @@ -110,5 +110,31 @@ public static void RegisterSynchronization( $"{transaction.GetType()} does not support {nameof(ITransactionCompletionSynchronization)}"); registerMethod.Invoke(transaction, new object[] { synchronization }); } + + public static Task BeginAsync(this ITransaction transaction, IsolationLevel isolationLevel) + { + try + { + transaction.Begin(isolationLevel); + return Task.CompletedTask; + } + catch (Exception ex) + { + return Task.FromException(ex); + } + } + + public static Task BeginAsync(this ITransaction transaction) + { + try + { + transaction.Begin(); + return Task.CompletedTask; + } + catch (Exception ex) + { + return Task.FromException(ex); + } + } } } From 69376ba82b1fe770807c1089652e87e8b45e6832 Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Thu, 1 Sep 2022 01:23:34 +0000 Subject: [PATCH 13/30] Update AsyncGenerator.yml --- src/AsyncGenerator.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AsyncGenerator.yml b/src/AsyncGenerator.yml index 0d01d26e491..7b96993fbc7 100644 --- a/src/AsyncGenerator.yml +++ b/src/AsyncGenerator.yml @@ -126,7 +126,7 @@ containingTypeName: IBatcher - conversion: ToAsync name: BeginTransaction - containingTypeName: ConnectionManager + containingTypeName: DriverBase - conversion: ToAsync rule: EventListener - conversion: ToAsync From b5a3e3529d1d37de05742c5dc089c9d728abf002 Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Thu, 1 Sep 2022 01:24:57 +0000 Subject: [PATCH 14/30] Update ITransaction.cs --- src/NHibernate/ITransaction.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/NHibernate/ITransaction.cs b/src/NHibernate/ITransaction.cs index 19d4e67788e..c9f87032395 100644 --- a/src/NHibernate/ITransaction.cs +++ b/src/NHibernate/ITransaction.cs @@ -1,6 +1,7 @@ using System; using System.Data; using System.Data.Common; +using System.Threading.Tasks; using NHibernate.Transaction; namespace NHibernate From 275cdd1399cf2f88f6c302d9d55db77a88f0e727 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 1 Sep 2022 01:27:43 +0000 Subject: [PATCH 15/30] Generate async files --- .../TransactionNotificationFixture.cs | 10 ++++ .../Async/AdoNet/ConnectionManager.cs | 26 +++----- src/NHibernate/Async/Driver/DriverBase.cs | 51 ++++++++++++++++ .../Async/Driver/DriverExtensions.cs | 54 +++++++++++++++++ src/NHibernate/Async/ITransaction.cs | 12 +++- .../Async/Transaction/AdoTransaction.cs | 59 +++++++++++++++++++ src/NHibernate/Driver/DriverExtensions.cs | 2 +- 7 files changed, 194 insertions(+), 20 deletions(-) create mode 100644 src/NHibernate/Async/Driver/DriverBase.cs create mode 100644 src/NHibernate/Async/Driver/DriverExtensions.cs diff --git a/src/NHibernate.Test/Async/TransactionTest/TransactionNotificationFixture.cs b/src/NHibernate.Test/Async/TransactionTest/TransactionNotificationFixture.cs index bf9a1f445a1..40f3dd5b071 100644 --- a/src/NHibernate.Test/Async/TransactionTest/TransactionNotificationFixture.cs +++ b/src/NHibernate.Test/Async/TransactionTest/TransactionNotificationFixture.cs @@ -138,6 +138,16 @@ public async Task ShouldNotifyAfterTransactionWithOwnConnectionAsync(bool usePre public partial class CustomTransaction : ITransaction { + public Task BeginAsync() + { + throw new NotImplementedException(); + } + + public Task BeginAsync(IsolationLevel isolationLevel) + { + throw new NotImplementedException(); + } + public Task CommitAsync(CancellationToken cancellationToken = default(CancellationToken)) { throw new NotImplementedException(); diff --git a/src/NHibernate/Async/AdoNet/ConnectionManager.cs b/src/NHibernate/Async/AdoNet/ConnectionManager.cs index 029b5c7b209..feb67ed35c6 100644 --- a/src/NHibernate/Async/AdoNet/ConnectionManager.cs +++ b/src/NHibernate/Async/AdoNet/ConnectionManager.cs @@ -106,28 +106,18 @@ async Task InternalGetConnectionAsync() } } - public Task BeginTransactionAsync(IsolationLevel isolationLevel) + public async Task BeginTransactionAsync(IsolationLevel isolationLevel) { - try - { - return Task.FromResult(BeginTransaction(isolationLevel)); - } - catch (Exception ex) - { - return Task.FromException(ex); - } + EnsureTransactionIsCreated(); + await (_transaction.BeginAsync(isolationLevel)).ConfigureAwait(false); + return _transaction; } - public Task BeginTransactionAsync() + public async Task BeginTransactionAsync() { - try - { - return Task.FromResult(BeginTransaction()); - } - catch (Exception ex) - { - return Task.FromException(ex); - } + EnsureTransactionIsCreated(); + await (_transaction.BeginAsync()).ConfigureAwait(false); + return _transaction; } public async Task CreateCommandAsync(CancellationToken cancellationToken) diff --git a/src/NHibernate/Async/Driver/DriverBase.cs b/src/NHibernate/Async/Driver/DriverBase.cs new file mode 100644 index 00000000000..1f2c8b1d3fc --- /dev/null +++ b/src/NHibernate/Async/Driver/DriverBase.cs @@ -0,0 +1,51 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by AsyncGenerator. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + + +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using NHibernate.Engine; +using NHibernate.SqlCommand; +using NHibernate.SqlTypes; +using NHibernate.Util; +using Environment = NHibernate.Cfg.Environment; + +namespace NHibernate.Driver +{ + using System.Threading.Tasks; + public abstract partial class DriverBase : IDriver, ISqlParameterFormatter + { + + /// + /// Begin an ADO . + /// + /// The isolation level requested for the transaction. + /// The connection on which to start the transaction. + /// The started . + public virtual Task BeginTransactionAsync(IsolationLevel isolationLevel, DbConnection connection) + { + try + { + return Task.FromResult(BeginTransaction(isolationLevel, connection)); + } + catch (Exception ex) + { + return Task.FromException(ex); + } + } + + #if NETFX + #else + + #endif + } +} diff --git a/src/NHibernate/Async/Driver/DriverExtensions.cs b/src/NHibernate/Async/Driver/DriverExtensions.cs new file mode 100644 index 00000000000..fcc5610ccfe --- /dev/null +++ b/src/NHibernate/Async/Driver/DriverExtensions.cs @@ -0,0 +1,54 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by AsyncGenerator. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + + +using System.Data; +using System.Data.Common; +using NHibernate.AdoNet; +using NHibernate.SqlTypes; +using NHibernate.Util; + +namespace NHibernate.Driver +{ + using System.Threading.Tasks; + public static partial class DriverExtensions + { + + // 6.0 TODO: merge into IDriver + /// + /// Begin an ADO . + /// + /// The driver. + /// The isolation level requested for the transaction. + /// The connection on which to start the transaction. + /// The started . + public static Task BeginTransactionAsync(this IDriver driver, IsolationLevel isolationLevel, DbConnection connection) + { + try + { + if (driver is DriverBase driverBase) + { + return driverBase.BeginTransactionAsync(isolationLevel, connection); + } + + // So long for custom drivers not deriving from DriverBase, they will have to wait for 6.0 if they + // need the feature. + if (isolationLevel == IsolationLevel.Unspecified) + { + return Task.FromResult(connection.BeginTransaction()); + } + return Task.FromResult(connection.BeginTransaction(isolationLevel)); + } + catch (System.Exception ex) + { + return Task.FromException(ex); + } + } + } +} diff --git a/src/NHibernate/Async/ITransaction.cs b/src/NHibernate/Async/ITransaction.cs index ea6ea4b3ab9..9b0a7e79b46 100644 --- a/src/NHibernate/Async/ITransaction.cs +++ b/src/NHibernate/Async/ITransaction.cs @@ -11,14 +11,24 @@ using System; using System.Data; using System.Data.Common; +using System.Threading.Tasks; using NHibernate.Transaction; namespace NHibernate { - using System.Threading.Tasks; using System.Threading; public partial interface ITransaction : IDisposable { + /// + /// Begin the transaction with the default isolation level. + /// + Task BeginAsync(); + + /// + /// Begin the transaction with the specified isolation level. + /// + /// Isolation level of the transaction + Task BeginAsync(IsolationLevel isolationLevel); /// /// Flush the associated ISession and end the unit of work. diff --git a/src/NHibernate/Async/Transaction/AdoTransaction.cs b/src/NHibernate/Async/Transaction/AdoTransaction.cs index a8b249130fa..8a3fe900c88 100644 --- a/src/NHibernate/Async/Transaction/AdoTransaction.cs +++ b/src/NHibernate/Async/Transaction/AdoTransaction.cs @@ -23,6 +23,65 @@ namespace NHibernate.Transaction public partial class AdoTransaction : ITransaction { + public Task BeginAsync() + { + return BeginAsync(IsolationLevel.Unspecified); + } + + /// + /// Begins the on the + /// used by the . + /// + /// + /// Thrown if there is any problems encountered while trying to create + /// the . + /// + public async Task BeginAsync(IsolationLevel isolationLevel) + { + using (session.BeginProcess()) + { + if (begun) + { + return; + } + + if (commitFailed) + { + throw new TransactionException("Cannot restart transaction after failed commit"); + } + + if (isolationLevel == IsolationLevel.Unspecified) + { + isolationLevel = session.Factory.Settings.IsolationLevel; + } + + log.Debug("Begin ({0})", isolationLevel); + + try + { + trans = await (session.Factory.ConnectionProvider.Driver.BeginTransactionAsync(isolationLevel, session.Connection)).ConfigureAwait(false); + } + catch (HibernateException) + { + // Don't wrap HibernateExceptions + throw; + } + catch (Exception e) + { + log.Error(e, "Begin transaction failed"); + throw new TransactionException("Begin failed with SQL exception", e); + } + + begun = true; + committed = false; + rolledBack = false; + + session.AfterTransactionBegin(this); + foreach (var dependentSession in session.ConnectionManager.DependentSessions) + dependentSession.AfterTransactionBegin(this); + } + } + private async Task AfterTransactionCompletionAsync(bool successful, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); diff --git a/src/NHibernate/Driver/DriverExtensions.cs b/src/NHibernate/Driver/DriverExtensions.cs index d370269c35e..3bf194d61ba 100644 --- a/src/NHibernate/Driver/DriverExtensions.cs +++ b/src/NHibernate/Driver/DriverExtensions.cs @@ -6,7 +6,7 @@ namespace NHibernate.Driver { - public static class DriverExtensions + public static partial class DriverExtensions { internal static void AdjustParameterForValue(this IDriver driver, DbParameter parameter, SqlType sqlType, object value) { From d792db3a1e4f7d5297a626ff8ac0137002bf0787 Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Thu, 1 Sep 2022 01:36:29 +0000 Subject: [PATCH 16/30] Update AsyncExtensions.cs --- src/NHibernate/AdoNet/AsyncExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NHibernate/AdoNet/AsyncExtensions.cs b/src/NHibernate/AdoNet/AsyncExtensions.cs index 29cc2d83c6f..95bba524cc1 100644 --- a/src/NHibernate/AdoNet/AsyncExtensions.cs +++ b/src/NHibernate/AdoNet/AsyncExtensions.cs @@ -3,7 +3,7 @@ using System.Threading; using System.Threading.Tasks; -namespace System.Data.Common +namespace NHibernate { internal static class AsyncExtensions { From c0e48adb75ac504b238b7dd3b02429abad4da07a Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Thu, 1 Sep 2022 14:30:20 +1200 Subject: [PATCH 17/30] Fix async extensions --- src/NHibernate/AdoNet/AsyncExtensions.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/NHibernate/AdoNet/AsyncExtensions.cs b/src/NHibernate/AdoNet/AsyncExtensions.cs index 95bba524cc1..55e0b8d7c1a 100644 --- a/src/NHibernate/AdoNet/AsyncExtensions.cs +++ b/src/NHibernate/AdoNet/AsyncExtensions.cs @@ -1,5 +1,7 @@ #if NETFX || NETSTANDARD2_0 || NETCOREAPP2_0 using System; +using System.Data; +using System.Data.Common; using System.Threading; using System.Threading.Tasks; From 15c32eea1902b1f88e3156bd1fa49947081d2081 Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Wed, 14 Sep 2022 21:46:53 +0000 Subject: [PATCH 18/30] Register AsyncExtensions.cs --- src/AsyncGenerator.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/AsyncGenerator.yml b/src/AsyncGenerator.yml index 7b96993fbc7..580362c0491 100644 --- a/src/AsyncGenerator.yml +++ b/src/AsyncGenerator.yml @@ -215,6 +215,8 @@ projectFiles: - fileName: LinqExtensionMethods.cs projectName: NHibernate + - fileName: AsyncExtensions.cs + projectName: NHibernate typeConversion: - conversion: Ignore name: ObjectAssert From dad96b8f60954f8532c186500d7f8372965bea3f Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Wed, 14 Sep 2022 21:47:48 +0000 Subject: [PATCH 19/30] Make IDriver not partial --- src/NHibernate/Driver/IDriver.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NHibernate/Driver/IDriver.cs b/src/NHibernate/Driver/IDriver.cs index 71ae3c0a10d..61e40b64213 100644 --- a/src/NHibernate/Driver/IDriver.cs +++ b/src/NHibernate/Driver/IDriver.cs @@ -30,7 +30,7 @@ namespace NHibernate.Driver /// value="FullyQualifiedClassName, AssemblyName" /// /// - public partial interface IDriver + public interface IDriver { /// /// Configure the driver using . From 2e79402c291712d5cfaf45a4bc1f0b97ef8db582 Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Wed, 14 Sep 2022 21:59:01 +0000 Subject: [PATCH 20/30] Update AsyncGenerator.yml --- src/AsyncGenerator.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/AsyncGenerator.yml b/src/AsyncGenerator.yml index 580362c0491..a63e3cf01a5 100644 --- a/src/AsyncGenerator.yml +++ b/src/AsyncGenerator.yml @@ -142,6 +142,10 @@ - conversion: Ignore name: DependentContext containingTypeName: AdoNetWithSystemTransactionFactory + asyncExtensionMethods: + projectFiles: + - fileName: AsyncExtensions.cs + projectName: NHibernate ignoreSearchForAsyncCounterparts: - name: GetFieldValue - name: IsDBNull From fccd63c66cbe810fffdda2cfc0f868be75ee92b5 Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Thu, 15 Sep 2022 21:12:44 +0000 Subject: [PATCH 21/30] Update dotnet-tools.json --- .config/dotnet-tools.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 34480f2f9b4..8f1e9991d2e 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "csharpasyncgenerator.tool": { - "version": "0.20.1", + "version": "0.21.0", "commands": [ "async-generator" ] @@ -15,4 +15,4 @@ ] } } -} \ No newline at end of file +} From 214653304148ac8086fcd0533df853f3ae184aaa Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 15 Sep 2022 21:15:14 +0000 Subject: [PATCH 22/30] Generate async files --- .../TransactionNotificationFixture.cs | 4 ++-- src/NHibernate/Async/AdoNet/ConnectionManager.cs | 10 ++++++---- src/NHibernate/Async/Driver/DriverBase.cs | 14 ++++++++++++-- src/NHibernate/Async/Driver/DriverExtensions.cs | 14 ++++++++++---- src/NHibernate/Async/ITransaction.cs | 6 ++++-- src/NHibernate/Async/Impl/AbstractSessionImpl.cs | 12 ++++++++---- .../Async/Transaction/AdoNetTransactionFactory.cs | 2 +- src/NHibernate/Async/Transaction/AdoTransaction.cs | 14 ++++++++++---- 8 files changed, 53 insertions(+), 23 deletions(-) diff --git a/src/NHibernate.Test/Async/TransactionTest/TransactionNotificationFixture.cs b/src/NHibernate.Test/Async/TransactionTest/TransactionNotificationFixture.cs index 40f3dd5b071..49f64598152 100644 --- a/src/NHibernate.Test/Async/TransactionTest/TransactionNotificationFixture.cs +++ b/src/NHibernate.Test/Async/TransactionTest/TransactionNotificationFixture.cs @@ -138,12 +138,12 @@ public async Task ShouldNotifyAfterTransactionWithOwnConnectionAsync(bool usePre public partial class CustomTransaction : ITransaction { - public Task BeginAsync() + public Task BeginAsync(CancellationToken cancellationToken = default(CancellationToken)) { throw new NotImplementedException(); } - public Task BeginAsync(IsolationLevel isolationLevel) + public Task BeginAsync(IsolationLevel isolationLevel, CancellationToken cancellationToken = default(CancellationToken)) { throw new NotImplementedException(); } diff --git a/src/NHibernate/Async/AdoNet/ConnectionManager.cs b/src/NHibernate/Async/AdoNet/ConnectionManager.cs index feb67ed35c6..e209d7aee73 100644 --- a/src/NHibernate/Async/AdoNet/ConnectionManager.cs +++ b/src/NHibernate/Async/AdoNet/ConnectionManager.cs @@ -106,17 +106,19 @@ async Task InternalGetConnectionAsync() } } - public async Task BeginTransactionAsync(IsolationLevel isolationLevel) + public async Task BeginTransactionAsync(IsolationLevel isolationLevel, CancellationToken cancellationToken) { + cancellationToken.ThrowIfCancellationRequested(); EnsureTransactionIsCreated(); - await (_transaction.BeginAsync(isolationLevel)).ConfigureAwait(false); + await (_transaction.BeginAsync(isolationLevel, cancellationToken)).ConfigureAwait(false); return _transaction; } - public async Task BeginTransactionAsync() + public async Task BeginTransactionAsync(CancellationToken cancellationToken) { + cancellationToken.ThrowIfCancellationRequested(); EnsureTransactionIsCreated(); - await (_transaction.BeginAsync()).ConfigureAwait(false); + await (_transaction.BeginAsync(cancellationToken)).ConfigureAwait(false); return _transaction; } diff --git a/src/NHibernate/Async/Driver/DriverBase.cs b/src/NHibernate/Async/Driver/DriverBase.cs index 1f2c8b1d3fc..a0c5c0e4eb5 100644 --- a/src/NHibernate/Async/Driver/DriverBase.cs +++ b/src/NHibernate/Async/Driver/DriverBase.cs @@ -22,6 +22,7 @@ namespace NHibernate.Driver { using System.Threading.Tasks; + using System.Threading; public abstract partial class DriverBase : IDriver, ISqlParameterFormatter { @@ -30,12 +31,21 @@ public abstract partial class DriverBase : IDriver, ISqlParameterFormatter /// /// The isolation level requested for the transaction. /// The connection on which to start the transaction. + /// A cancellation token that can be used to cancel the work /// The started . - public virtual Task BeginTransactionAsync(IsolationLevel isolationLevel, DbConnection connection) + public virtual Task BeginTransactionAsync(IsolationLevel isolationLevel, DbConnection connection, CancellationToken cancellationToken) { + if (cancellationToken.IsCancellationRequested) + { + return Task.FromCanceled(cancellationToken); + } try { - return Task.FromResult(BeginTransaction(isolationLevel, connection)); + if (isolationLevel == IsolationLevel.Unspecified) + { + return connection.BeginTransactionAsync(cancellationToken); + } + return connection.BeginTransactionAsync(isolationLevel, cancellationToken); } catch (Exception ex) { diff --git a/src/NHibernate/Async/Driver/DriverExtensions.cs b/src/NHibernate/Async/Driver/DriverExtensions.cs index fcc5610ccfe..b6c9bc3a0f5 100644 --- a/src/NHibernate/Async/Driver/DriverExtensions.cs +++ b/src/NHibernate/Async/Driver/DriverExtensions.cs @@ -17,6 +17,7 @@ namespace NHibernate.Driver { using System.Threading.Tasks; + using System.Threading; public static partial class DriverExtensions { @@ -27,23 +28,28 @@ public static partial class DriverExtensions /// The driver. /// The isolation level requested for the transaction. /// The connection on which to start the transaction. + /// A cancellation token that can be used to cancel the work /// The started . - public static Task BeginTransactionAsync(this IDriver driver, IsolationLevel isolationLevel, DbConnection connection) + public static Task BeginTransactionAsync(this IDriver driver, IsolationLevel isolationLevel, DbConnection connection, CancellationToken cancellationToken) { + if (cancellationToken.IsCancellationRequested) + { + return Task.FromCanceled(cancellationToken); + } try { if (driver is DriverBase driverBase) { - return driverBase.BeginTransactionAsync(isolationLevel, connection); + return driverBase.BeginTransactionAsync(isolationLevel, connection, cancellationToken); } // So long for custom drivers not deriving from DriverBase, they will have to wait for 6.0 if they // need the feature. if (isolationLevel == IsolationLevel.Unspecified) { - return Task.FromResult(connection.BeginTransaction()); + return connection.BeginTransactionAsync(cancellationToken); } - return Task.FromResult(connection.BeginTransaction(isolationLevel)); + return connection.BeginTransactionAsync(isolationLevel, cancellationToken); } catch (System.Exception ex) { diff --git a/src/NHibernate/Async/ITransaction.cs b/src/NHibernate/Async/ITransaction.cs index 9b0a7e79b46..bf84f852bfa 100644 --- a/src/NHibernate/Async/ITransaction.cs +++ b/src/NHibernate/Async/ITransaction.cs @@ -22,13 +22,15 @@ public partial interface ITransaction : IDisposable /// /// Begin the transaction with the default isolation level. /// - Task BeginAsync(); + /// A cancellation token that can be used to cancel the work + Task BeginAsync(CancellationToken cancellationToken = default(CancellationToken)); /// /// Begin the transaction with the specified isolation level. /// /// Isolation level of the transaction - Task BeginAsync(IsolationLevel isolationLevel); + /// A cancellation token that can be used to cancel the work + Task BeginAsync(IsolationLevel isolationLevel, CancellationToken cancellationToken = default(CancellationToken)); /// /// Flush the associated ISession and end the unit of work. diff --git a/src/NHibernate/Async/Impl/AbstractSessionImpl.cs b/src/NHibernate/Async/Impl/AbstractSessionImpl.cs index 718a0ed72f2..770634cb5c9 100644 --- a/src/NHibernate/Async/Impl/AbstractSessionImpl.cs +++ b/src/NHibernate/Async/Impl/AbstractSessionImpl.cs @@ -215,9 +215,11 @@ protected async Task AfterOperationAsync(bool success, CancellationToken cancell /// /// Begin a NHibernate transaction /// + /// A cancellation token that can be used to cancel the work /// A NHibernate transaction - public async Task BeginTransactionAsync() + public async Task BeginTransactionAsync(CancellationToken cancellationToken) { + cancellationToken.ThrowIfCancellationRequested(); using (BeginProcess()) { if (IsTransactionCoordinatorShared) @@ -227,7 +229,7 @@ public async Task BeginTransactionAsync() Log.Warn("Transaction started on non-root session"); } - return await (ConnectionManager.BeginTransactionAsync()).ConfigureAwait(false); + return await (ConnectionManager.BeginTransactionAsync(cancellationToken)).ConfigureAwait(false); } } @@ -235,9 +237,11 @@ public async Task BeginTransactionAsync() /// Begin a NHibernate transaction with the specified isolation level /// /// The isolation level + /// A cancellation token that can be used to cancel the work /// A NHibernate transaction - public async Task BeginTransactionAsync(IsolationLevel isolationLevel) + public async Task BeginTransactionAsync(IsolationLevel isolationLevel, CancellationToken cancellationToken) { + cancellationToken.ThrowIfCancellationRequested(); using (BeginProcess()) { if (IsTransactionCoordinatorShared) @@ -247,7 +251,7 @@ public async Task BeginTransactionAsync(IsolationLevel isolationLe Log.Warn("Transaction started on non-root session"); } - return await (ConnectionManager.BeginTransactionAsync(isolationLevel)).ConfigureAwait(false); + return await (ConnectionManager.BeginTransactionAsync(isolationLevel, cancellationToken)).ConfigureAwait(false); } } diff --git a/src/NHibernate/Async/Transaction/AdoNetTransactionFactory.cs b/src/NHibernate/Async/Transaction/AdoNetTransactionFactory.cs index 2fd5c3fa458..41da2ed1eb5 100644 --- a/src/NHibernate/Async/Transaction/AdoNetTransactionFactory.cs +++ b/src/NHibernate/Async/Transaction/AdoNetTransactionFactory.cs @@ -51,7 +51,7 @@ async Task InternalExecuteWorkInIsolationAsync() if (transacted) { - trans = connection.BeginTransaction(); + trans = await (connection.BeginTransactionAsync(cancellationToken)).ConfigureAwait(false); } await (work.DoWorkAsync(connection, trans, cancellationToken)).ConfigureAwait(false); diff --git a/src/NHibernate/Async/Transaction/AdoTransaction.cs b/src/NHibernate/Async/Transaction/AdoTransaction.cs index 8a3fe900c88..97009f4ae72 100644 --- a/src/NHibernate/Async/Transaction/AdoTransaction.cs +++ b/src/NHibernate/Async/Transaction/AdoTransaction.cs @@ -23,9 +23,13 @@ namespace NHibernate.Transaction public partial class AdoTransaction : ITransaction { - public Task BeginAsync() + public Task BeginAsync(CancellationToken cancellationToken = default(CancellationToken)) { - return BeginAsync(IsolationLevel.Unspecified); + if (cancellationToken.IsCancellationRequested) + { + return Task.FromCanceled(cancellationToken); + } + return BeginAsync(IsolationLevel.Unspecified, cancellationToken); } /// @@ -36,8 +40,9 @@ public Task BeginAsync() /// Thrown if there is any problems encountered while trying to create /// the . /// - public async Task BeginAsync(IsolationLevel isolationLevel) + public async Task BeginAsync(IsolationLevel isolationLevel, CancellationToken cancellationToken = default(CancellationToken)) { + cancellationToken.ThrowIfCancellationRequested(); using (session.BeginProcess()) { if (begun) @@ -59,8 +64,9 @@ public async Task BeginAsync(IsolationLevel isolationLevel) try { - trans = await (session.Factory.ConnectionProvider.Driver.BeginTransactionAsync(isolationLevel, session.Connection)).ConfigureAwait(false); + trans = await (session.Factory.ConnectionProvider.Driver.BeginTransactionAsync(isolationLevel, session.Connection, cancellationToken)).ConfigureAwait(false); } + catch (OperationCanceledException) { throw; } catch (HibernateException) { // Don't wrap HibernateExceptions From f344e0f11f32ade40c6fa8237cab189837618ddd Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Thu, 15 Sep 2022 21:26:39 +0000 Subject: [PATCH 23/30] Update AsyncGenerator.yml --- src/AsyncGenerator.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/AsyncGenerator.yml b/src/AsyncGenerator.yml index a63e3cf01a5..174952d5400 100644 --- a/src/AsyncGenerator.yml +++ b/src/AsyncGenerator.yml @@ -142,6 +142,9 @@ - conversion: Ignore name: DependentContext containingTypeName: AdoNetWithSystemTransactionFactory + alwaysAwait: + - name BeginTransactionAsync + containingTypeName: AsyncExtensions asyncExtensionMethods: projectFiles: - fileName: AsyncExtensions.cs From 0ec8c4fc5f9d00b65b02185f525cb6c4b788f132 Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Thu, 15 Sep 2022 21:38:05 +0000 Subject: [PATCH 24/30] Update AsyncGenerator.yml --- src/AsyncGenerator.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/AsyncGenerator.yml b/src/AsyncGenerator.yml index 174952d5400..5c7bc618ede 100644 --- a/src/AsyncGenerator.yml +++ b/src/AsyncGenerator.yml @@ -133,6 +133,9 @@ rule: Cache - conversion: ToAsync rule: TransactionCompletion + alwaysAwait: + - name: BeginTransactionAsync + containingTypeName: AsyncExtensions typeConversion: - conversion: Ignore name: EnumerableImpl @@ -142,9 +145,6 @@ - conversion: Ignore name: DependentContext containingTypeName: AdoNetWithSystemTransactionFactory - alwaysAwait: - - name BeginTransactionAsync - containingTypeName: AsyncExtensions asyncExtensionMethods: projectFiles: - fileName: AsyncExtensions.cs From c5f899d94d14de2ddc7ff0e340d91b5a32ef093b Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Thu, 15 Sep 2022 21:46:04 +0000 Subject: [PATCH 25/30] Update AsyncGenerator.yml --- src/AsyncGenerator.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/AsyncGenerator.yml b/src/AsyncGenerator.yml index 5c7bc618ede..bf1e4fbc054 100644 --- a/src/AsyncGenerator.yml +++ b/src/AsyncGenerator.yml @@ -7,7 +7,7 @@ - pattern: ^.*(Hql\.g).*$ analyzation: methodConversion: -#TODO 6.0: Remove ignore rule for IQueryBatchItem.ProcessResults + #TODO 6.0: Remove ignore rule for IQueryBatchItem.ProcessResults - conversion: Ignore name: ProcessResults containingTypeName: IQueryBatchItem @@ -62,7 +62,7 @@ - conversion: Ignore name: CloseSessionFromSystemTransaction containingTypeName: ISessionImplementor -# TODO 6.0: Remove ignore rule for IStatelessSession.Close + # TODO 6.0: Remove ignore rule for IStatelessSession.Close - conversion: Ignore name: Close containingTypeName: IStatelessSession @@ -114,7 +114,7 @@ - conversion: Ignore name: GetEnumerator containingTypeName: IFutureEnumerable -# TODO 6.0: Consider if ComputeFlattenedParameters should remain ignored or not + # TODO 6.0: Consider if ComputeFlattenedParameters should remain ignored or not - conversion: Ignore name: ComputeFlattenedParameters containingTypeName: SqlQueryImpl @@ -134,8 +134,7 @@ - conversion: ToAsync rule: TransactionCompletion alwaysAwait: - - name: BeginTransactionAsync - containingTypeName: AsyncExtensions + - filter: BeginTransactionAsync typeConversion: - conversion: Ignore name: EnumerableImpl @@ -319,6 +318,10 @@ methodRules: - filters: - hasAttributeName: ObsoleteAttribute name: Obsolete +- filters: + - containingTypeName: AsyncExtensions + name: BeginTransactionAsync + name: BeginTransactionAsync typeRules: - filters: - containingAssemblyName: NHibernate From 13e53c4665a1e6c17252188570b6d7830acaa1d8 Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Thu, 15 Sep 2022 21:47:35 +0000 Subject: [PATCH 26/30] Update AsyncGenerator.yml --- src/AsyncGenerator.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/AsyncGenerator.yml b/src/AsyncGenerator.yml index bf1e4fbc054..7e8c7116741 100644 --- a/src/AsyncGenerator.yml +++ b/src/AsyncGenerator.yml @@ -1,4 +1,4 @@ -projects: +projects: - filePath: NHibernate/NHibernate.csproj targetFramework: netcoreapp2.0 concurrentRun: true @@ -134,7 +134,7 @@ - conversion: ToAsync rule: TransactionCompletion alwaysAwait: - - filter: BeginTransactionAsync + - rule: BeginTransactionAsync typeConversion: - conversion: Ignore name: EnumerableImpl From 7a482b926320a52601508cf531bdcfb587af9daa Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Thu, 15 Sep 2022 21:54:27 +0000 Subject: [PATCH 27/30] Update AsyncGenerator.yml --- src/AsyncGenerator.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/AsyncGenerator.yml b/src/AsyncGenerator.yml index 7e8c7116741..0d75a8be082 100644 --- a/src/AsyncGenerator.yml +++ b/src/AsyncGenerator.yml @@ -320,7 +320,6 @@ methodRules: name: Obsolete - filters: - containingTypeName: AsyncExtensions - name: BeginTransactionAsync name: BeginTransactionAsync typeRules: - filters: From b446b282668c062a5608cfbe5c170b29bc41da39 Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Thu, 15 Sep 2022 22:01:25 +0000 Subject: [PATCH 28/30] Update AsyncGenerator.yml --- src/AsyncGenerator.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AsyncGenerator.yml b/src/AsyncGenerator.yml index 0d75a8be082..2d64aea8316 100644 --- a/src/AsyncGenerator.yml +++ b/src/AsyncGenerator.yml @@ -1,6 +1,6 @@ projects: - filePath: NHibernate/NHibernate.csproj - targetFramework: netcoreapp2.0 + targetFramework: netcoreapp2.1 concurrentRun: true applyChanges: true suppressDiagnosticFailures: From 74415d1b120edc5138e84d6ce31d490b41a1b0ff Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Thu, 15 Sep 2022 23:01:49 +0000 Subject: [PATCH 29/30] Update AsyncGenerator.yml --- src/AsyncGenerator.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/AsyncGenerator.yml b/src/AsyncGenerator.yml index 2d64aea8316..883085fc45a 100644 --- a/src/AsyncGenerator.yml +++ b/src/AsyncGenerator.yml @@ -1,6 +1,6 @@ projects: - filePath: NHibernate/NHibernate.csproj - targetFramework: netcoreapp2.1 + targetFramework: netcoreapp2.0 concurrentRun: true applyChanges: true suppressDiagnosticFailures: @@ -134,7 +134,7 @@ projects: - conversion: ToAsync rule: TransactionCompletion alwaysAwait: - - rule: BeginTransactionAsync + - name: BeginTransaction typeConversion: - conversion: Ignore name: EnumerableImpl From 5c98a5456d4b7381b49df6c7297da0921f5f036c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 15 Sep 2022 23:04:21 +0000 Subject: [PATCH 30/30] Generate async files --- src/NHibernate/Async/Driver/DriverBase.cs | 20 ++++--------- .../Async/Driver/DriverExtensions.cs | 28 ++++++------------- 2 files changed, 14 insertions(+), 34 deletions(-) diff --git a/src/NHibernate/Async/Driver/DriverBase.cs b/src/NHibernate/Async/Driver/DriverBase.cs index a0c5c0e4eb5..a1f6d1c68c2 100644 --- a/src/NHibernate/Async/Driver/DriverBase.cs +++ b/src/NHibernate/Async/Driver/DriverBase.cs @@ -33,24 +33,14 @@ public abstract partial class DriverBase : IDriver, ISqlParameterFormatter /// The connection on which to start the transaction. /// A cancellation token that can be used to cancel the work /// The started . - public virtual Task BeginTransactionAsync(IsolationLevel isolationLevel, DbConnection connection, CancellationToken cancellationToken) + public virtual async Task BeginTransactionAsync(IsolationLevel isolationLevel, DbConnection connection, CancellationToken cancellationToken) { - if (cancellationToken.IsCancellationRequested) + cancellationToken.ThrowIfCancellationRequested(); + if (isolationLevel == IsolationLevel.Unspecified) { - return Task.FromCanceled(cancellationToken); - } - try - { - if (isolationLevel == IsolationLevel.Unspecified) - { - return connection.BeginTransactionAsync(cancellationToken); - } - return connection.BeginTransactionAsync(isolationLevel, cancellationToken); - } - catch (Exception ex) - { - return Task.FromException(ex); + return await (connection.BeginTransactionAsync(cancellationToken)).ConfigureAwait(false); } + return await (connection.BeginTransactionAsync(isolationLevel, cancellationToken)).ConfigureAwait(false); } #if NETFX diff --git a/src/NHibernate/Async/Driver/DriverExtensions.cs b/src/NHibernate/Async/Driver/DriverExtensions.cs index b6c9bc3a0f5..ca1150bf957 100644 --- a/src/NHibernate/Async/Driver/DriverExtensions.cs +++ b/src/NHibernate/Async/Driver/DriverExtensions.cs @@ -30,31 +30,21 @@ public static partial class DriverExtensions /// The connection on which to start the transaction. /// A cancellation token that can be used to cancel the work /// The started . - public static Task BeginTransactionAsync(this IDriver driver, IsolationLevel isolationLevel, DbConnection connection, CancellationToken cancellationToken) + public static async Task BeginTransactionAsync(this IDriver driver, IsolationLevel isolationLevel, DbConnection connection, CancellationToken cancellationToken) { - if (cancellationToken.IsCancellationRequested) + cancellationToken.ThrowIfCancellationRequested(); + if (driver is DriverBase driverBase) { - return Task.FromCanceled(cancellationToken); + return await (driverBase.BeginTransactionAsync(isolationLevel, connection, cancellationToken)).ConfigureAwait(false); } - try - { - if (driver is DriverBase driverBase) - { - return driverBase.BeginTransactionAsync(isolationLevel, connection, cancellationToken); - } - // So long for custom drivers not deriving from DriverBase, they will have to wait for 6.0 if they - // need the feature. - if (isolationLevel == IsolationLevel.Unspecified) - { - return connection.BeginTransactionAsync(cancellationToken); - } - return connection.BeginTransactionAsync(isolationLevel, cancellationToken); - } - catch (System.Exception ex) + // So long for custom drivers not deriving from DriverBase, they will have to wait for 6.0 if they + // need the feature. + if (isolationLevel == IsolationLevel.Unspecified) { - return Task.FromException(ex); + return await (connection.BeginTransactionAsync(cancellationToken)).ConfigureAwait(false); } + return await (connection.BeginTransactionAsync(isolationLevel, cancellationToken)).ConfigureAwait(false); } } }