Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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;
        }