Exemplo n.º 1
0
        /// <summary>
        /// Transactional Write procedure.
        /// </summary>
        public void Save()
        {
            var info = TransactionContext.GetTransactionInfo();

            if (this.logger.IsEnabled(LogLevel.Debug))
            {
                this.logger.Debug("Write {0}", info);
            }

            if (info.IsReadOnly)
            {
                // For obvious reasons...
                throw new OrleansReadOnlyViolatedException(info.TransactionId);
            }

            Rollback();

            var copiedValue = this.transactionCopy[info.TransactionId];

            //
            // Validation
            //

            if (this.version.TransactionId > info.TransactionId || this.highestReadTransactionId >= info.TransactionId)
            {
                // Prevent cycles. Wait-die
                throw new OrleansTransactionWaitDieException(info.TransactionId);
            }

            TransactionalResourceVersion nextVersion = TransactionalResourceVersion.Create(info.TransactionId,
                                                                                           this.version.TransactionId == info.TransactionId ? this.version.WriteNumber + 1 : 1);

            //
            // Update Transaction Context
            //
            info.RecordWrite(transactionalResource, this.version, this.metadata.StableVersion.TransactionId);

            //
            // Modify the State
            //
            if (!this.log.ContainsKey(info.TransactionId))
            {
                LogRecord <TState> r = new LogRecord <TState>();
                this.log[info.TransactionId] = r;
            }

            LogRecord <TState> logRecord = this.log[info.TransactionId];

            logRecord.NewVal  = copiedValue;
            logRecord.Version = nextVersion;
            this.value        = copiedValue;
            this.version      = nextVersion;

            this.transactionCopy.Remove(info.TransactionId);
        }
Exemplo n.º 2
0
        public async Task Commit(ITransactionInfo info)
        {
            var transactionInfo = (TransactionInfo)info;

            TransactionsStatisticsGroup.OnTransactionCommitRequest();

            if (transactionInfo.IsReadOnly)
            {
                return;
            }

            var  completion = new TaskCompletionSource <bool>();
            bool canCommit  = true;

            List <Task <bool> > prepareTasks = new List <Task <bool> >(transactionInfo.WriteSet.Count);

            foreach (var g in transactionInfo.WriteSet.Keys)
            {
                TransactionalResourceVersion write = TransactionalResourceVersion.Create(transactionInfo.TransactionId, transactionInfo.WriteSet[g]);
                TransactionalResourceVersion?read  = null;
                if (transactionInfo.ReadSet.ContainsKey(g))
                {
                    read = transactionInfo.ReadSet[g];
                    transactionInfo.ReadSet.Remove(g);
                }
                prepareTasks.Add(g.Prepare(transactionInfo.TransactionId, write, read));
            }

            foreach (var g in transactionInfo.ReadSet.Keys)
            {
                TransactionalResourceVersion read = transactionInfo.ReadSet[g];
                prepareTasks.Add(g.Prepare(transactionInfo.TransactionId, null, read));
            }

            await Task.WhenAll(prepareTasks);

            foreach (var t in prepareTasks)
            {
                if (!t.Result)
                {
                    canCommit = false;
                }
            }

            if (!canCommit)
            {
                TransactionsStatisticsGroup.OnTransactionAborted();
                abortedTransactions.TryAdd(transactionInfo.TransactionId, 0);
                throw new OrleansPrepareFailedException(transactionInfo.TransactionId);
            }
            commitCompletions.TryAdd(transactionInfo.TransactionId, completion);
            transactionCommitQueue.Enqueue(transactionInfo);
            await completion.Task;
        }
Exemplo n.º 3
0
 /// <summary>
 /// Read Log from persistent state interface.
 /// </summary>
 private void RevertToPersistedLog()
 {
     this.log.Clear();
     foreach (KeyValuePair <long, TState> kvp in this.storage.State.Logs)
     {
         this.log[kvp.Key] = new LogRecord <TState>
         {
             NewVal  = kvp.Value,
             Version = TransactionalResourceVersion.Create(kvp.Key, 1)
         };
     }
 }
Exemplo n.º 4
0
        /// <summary>
        /// Undo writes to restore state to pre transaction value.
        /// </summary>
        private void Rollback(long transactionId)
        {
            List <KeyValuePair <long, LogRecord <TState> > > records = this.log.SkipWhile(kvp => kvp.Key < transactionId).ToList();

            foreach (KeyValuePair <long, LogRecord <TState> > kvp in records)
            {
                this.log.Remove(kvp.Key);
                this.transactionCopy.Remove(kvp.Key);
            }

            if (this.log.Count > 0)
            {
                LogRecord <TState> lastLogRecord = this.log.Values.Last();
                this.version = lastLogRecord.Version;
                this.value   = lastLogRecord.NewVal;
            }
            else
            {
                this.version = TransactionalResourceVersion.Create(0, 0);
                this.value   = new TState();
            }
        }