/// <summary>
        /// Finish transaction, release lock and call done action
        /// </summary>
        private void Done()
        {
            ENSURE(_disposed == false, "transaction must be active before call Done");

            _disposed = true;

            _locker.ExitTransaction();

            _reader.Dispose();

            // call done callback
            _done(_transactionID);
        }
        /// <summary>
        /// Release current thread transaction
        /// </summary>
        public void ReleaseTransaction(TransactionService transaction)
        {
            // dispose current transaction
            transaction.Dispose();

            bool keepLocked;

            lock (_transactions)
            {
                // remove from "open transaction" list
                _transactions.Remove(transaction.TransactionID);

                // return freePages used area
                _freePages += transaction.MaxTransactionSize;

                // check if current thread contains more query transactions
                keepLocked = _transactions.Values.Any(x => x.ThreadID == Environment.CurrentManagedThreadId);
            }

            // unlock thread-transaction only if there is no more transactions
            if (keepLocked == false)
            {
                _locker.ExitTransaction();
            }

            // remove transaction from thread if are no queryOnly transaction
            if (transaction.QueryOnly == false)
            {
                ENSURE(_slot.Value == transaction, "current thread must contains transaction parameter");

                // clear thread slot for new transaction
                _slot.Value = null;
            }
        }