private bool CheckDependenciesCompleted() { bool processed = false; while (dependencyQueue.TryDequeue(out Transaction tx)) { processed = true; CommitRecord commitRecord = new CommitRecord { TransactionId = tx.TransactionId }; foreach (var resource in tx.Info.WriteSet.Keys) { commitRecord.Resources.Add(resource); } groupCommitQueue.Enqueue(new Tuple <CommitRecord, Transaction>(commitRecord, tx)); this.SignalGroupCommitEnqueued(); // We don't need to hold the transaction lock any more to access // the WaitingTransactions set, since nothing can be added to it // after this point. // If a transaction is waiting on us, decrement their waiting count; // - if they are no longer waiting, mark as validated. // TODO: Can't we clear WaitingTransactions here and no longer track it? foreach (var waiting in tx.WaitingTransactions) { bool signal = false; lock (waiting) { if (waiting.State != TransactionState.Aborted) { waiting.PendingCount--; if (waiting.PendingCount == 0) { waiting.State = TransactionState.Validated; dependencyQueue.Enqueue(waiting); signal = true; } } } if (signal) { this.SignalDependencyEnqueued(); } } } return(processed); }
public async Task StartAsync() { await transactionLog.Initialize(); CommitRecord record = await transactionLog.GetFirstCommitRecord(); long prevLSN = 0; while (record != null) { Transaction tx = new Transaction(record.TransactionId) { State = TransactionState.Committed, LSN = record.LSN, Info = new TransactionInfo(record.TransactionId) }; if (prevLSN == 0) { checkpointedLSN = record.LSN - 1; } prevLSN = record.LSN; foreach (var resource in record.Resources) { tx.Info.WriteSet.Add(resource, 1); } transactionsTable[record.TransactionId] = tx; checkpointQueue.Enqueue(tx); this.SignalCheckpointEnqueued(); record = await transactionLog.GetNextCommitRecord(); } await transactionLog.EndRecovery(); var maxAllocatedTransactionId = await transactionLog.GetStartRecord(); activeTransactionsTracker.Start(maxAllocatedTransactionId); this.BeginDependencyCompletionLoop(); this.BeginGroupCommitLoop(); this.BeginCheckpointLoop(); this.transactionLogMaintenanceTask = MaintainTransactionLog(); this.transactionLogMaintenanceTask.Ignore(); // protect agains unhandled exception in unexpected cases. this.IsRunning = true; }