From 48d89fd515f3ee348b13c5248d636bedd3a71611 Mon Sep 17 00:00:00 2001 From: neumannf Date: Sat, 26 Dec 2020 10:55:27 +0100 Subject: [PATCH] Fixed issue #1772: Unfortunately, the TransactionService for a closed thread was not be removed from the _transactions dictionary within the TransactionMonitor. Therefore a finalizer for the TransactionService was added, which takes care of removing the transaction from the _transactions dictionary. --- LiteDB/Engine/Services/TransactionService.cs | 28 +++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/LiteDB/Engine/Services/TransactionService.cs b/LiteDB/Engine/Services/TransactionService.cs index 5f03d71df..0a03e5837 100644 --- a/LiteDB/Engine/Services/TransactionService.cs +++ b/LiteDB/Engine/Services/TransactionService.cs @@ -74,6 +74,14 @@ public TransactionService(HeaderPage header, LockService locker, DiskService dis _reader = _disk.GetReader(); } + /// + /// Finalizer: Will be called once a thread is closed. The TransactionMonitor._slot releases the used TransactionService. + /// + ~TransactionService() + { + Dispose(false); + } + /// /// Create (or get from transaction-cache) snapshot and return /// @@ -375,10 +383,22 @@ IEnumerable source() } /// - /// Dispose + /// Public implementation of Dispose pattern. /// public void Dispose() { + Dispose(true); + GC.SuppressFinalize(this); + } + + // Protected implementation of Dispose pattern. + protected virtual void Dispose(bool dispose) + { + if (_state == TransactionState.Disposed) + { + return; + } + ENSURE(_state != TransactionState.Disposed, "transaction must be active before call Done"); // clean snapshots if there is no commit/rollback @@ -409,6 +429,12 @@ public void Dispose() _reader.Dispose(); _state = TransactionState.Disposed; + + if (!dispose) + { + // Remove transaction monitor's dictionary + _monitor.ReleaseTransaction(this); + } } } } \ No newline at end of file