public Transaction NewTransaction(TransactionFlags flags) { bool txLockTaken = false; try { long txId = _transactionsCounter; if (flags == (TransactionFlags.ReadWrite)) { txId = _transactionsCounter + 1; _txWriter.Wait(); txLockTaken = true; } var tx = new Transaction(_pager, this, txId, flags, _freeSpaceRepository); _activeTransactions.TryAdd(txId, tx); var state = _pager.TransactionBegan(); tx.AddPagerState(state); if (flags == TransactionFlags.ReadWrite) { _freeSpaceRepository.UpdateSections(tx, OldestTransaction); } return(tx); } catch (Exception) { if (txLockTaken) { _txWriter.Release(); } throw; } }
public Transaction NewTransaction(TransactionFlags flags, TimeSpan?timeout = null) { bool txLockTaken = false; try { if (flags == (TransactionFlags.ReadWrite)) { var wait = timeout ?? (Debugger.IsAttached ? TimeSpan.FromMinutes(30) : TimeSpan.FromSeconds(30)); if (_txWriter.Wait(wait) == false) { throw new TimeoutException("Waited for " + wait + " for transaction write lock, but could not get it"); } txLockTaken = true; if (_endOfDiskSpace != null) { if (_endOfDiskSpace.CanContinueWriting) { Debug.Assert(_flushingTask.Status == TaskStatus.Canceled || _flushingTask.Status == TaskStatus.RanToCompletion); _cancellationTokenSource = new CancellationTokenSource(); _flushingTask = FlushWritesToDataFileAsync(); _endOfDiskSpace = null; } } } long txId; Transaction tx; _txCommit.EnterReadLock(); try { txId = flags == TransactionFlags.ReadWrite ? _transactionsCounter + 1 : _transactionsCounter; tx = new Transaction(this, txId, flags, _freeSpaceHandling); } finally { _txCommit.ExitReadLock(); } _activeTransactions.Add(tx); var state = _dataPager.TransactionBegan(); tx.AddPagerState(state); if (flags == TransactionFlags.ReadWrite) { tx.AfterCommit = TransactionAfterCommit; } return(tx); } catch (Exception) { if (txLockTaken) { _txWriter.Release(); } throw; } }