From 39bff3261fc5142ae2718794742d5abced8bb026 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?= <12201973+fredericdelaporte@users.noreply.github.com> Date: Sat, 7 Aug 2021 23:10:38 +0200 Subject: [PATCH] Do not leave AdoTransaction in an inconsistent state Fix #2871 --- .../Async/Transaction/AdoTransaction.cs | 29 ++++++++++++------- src/NHibernate/Transaction/AdoTransaction.cs | 29 ++++++++++++------- 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/src/NHibernate/Async/Transaction/AdoTransaction.cs b/src/NHibernate/Async/Transaction/AdoTransaction.cs index 70ebb8c7684..dbbc3f550c9 100644 --- a/src/NHibernate/Async/Transaction/AdoTransaction.cs +++ b/src/NHibernate/Async/Transaction/AdoTransaction.cs @@ -170,20 +170,29 @@ protected virtual async Task DisposeAsync(bool isDisposing, CancellationToken ca // know this call came through Dispose() if (isDisposing) { - if (trans != null) + try { - trans.Dispose(); - trans = null; - log.Debug("DbTransaction disposed."); - } + if (trans != null) + { + trans.Dispose(); + trans = null; + log.Debug("DbTransaction disposed."); + } - if (IsActive && session != null) + if (IsActive && session != null) + { + // Assume we are rolled back + await (AfterTransactionCompletionAsync(false, cancellationToken)).ConfigureAwait(false); + } + // nothing for Finalizer to do - so tell the GC to ignore it + GC.SuppressFinalize(this); + } + finally { - // Assume we are rolled back - await (AfterTransactionCompletionAsync(false, cancellationToken)).ConfigureAwait(false); + // Do not leave the object in an inconsistent state in case of disposal failure: we should assume + // the DbTransaction is either no more ongoing or unrecoverable. + begun = false; } - // nothing for Finalizer to do - so tell the GC to ignore it - GC.SuppressFinalize(this); } // free unmanaged resources here diff --git a/src/NHibernate/Transaction/AdoTransaction.cs b/src/NHibernate/Transaction/AdoTransaction.cs index fe6d8b2b61c..8c20eb81acf 100644 --- a/src/NHibernate/Transaction/AdoTransaction.cs +++ b/src/NHibernate/Transaction/AdoTransaction.cs @@ -376,20 +376,29 @@ protected virtual void Dispose(bool isDisposing) // know this call came through Dispose() if (isDisposing) { - if (trans != null) + try { - trans.Dispose(); - trans = null; - log.Debug("DbTransaction disposed."); + if (trans != null) + { + trans.Dispose(); + trans = null; + log.Debug("DbTransaction disposed."); + } + + if (IsActive && session != null) + { + // Assume we are rolled back + AfterTransactionCompletion(false); + } + // nothing for Finalizer to do - so tell the GC to ignore it + GC.SuppressFinalize(this); } - - if (IsActive && session != null) + finally { - // Assume we are rolled back - AfterTransactionCompletion(false); + // Do not leave the object in an inconsistent state in case of disposal failure: we should assume + // the DbTransaction is either no more ongoing or unrecoverable. + begun = false; } - // nothing for Finalizer to do - so tell the GC to ignore it - GC.SuppressFinalize(this); } // free unmanaged resources here