public Task MultiGrainAdd(ITransactionCommitterTestGrain committer, ITransactionCommitOperation <IRemoteCommitService> operation, List <ITransactionTestGrain> grains, int numberToAdd) { List <Task> tasks = new List <Task>(); tasks.AddRange(grains.Select(g => g.Add(numberToAdd))); tasks.Add(committer.Commit(operation)); return(Task.WhenAll(tasks)); }
/// <inheritdoc/> public Task OnCommit(ITransactionCommitOperation <TService> operation) { if (operation == null) { throw new ArgumentNullException(nameof(operation)); } if (detectReentrancy) { throw new LockRecursionException("cannot perform an update operation from within another operation"); } var info = (TransactionInfo)TransactionContext.GetRequiredTransactionInfo <TransactionInfo>(); if (logger.IsEnabled(LogLevel.Trace)) { logger.Trace($"StartWrite {info}"); } if (info.IsReadOnly) { throw new OrleansReadOnlyViolatedException(info.Id); } info.Participants.TryGetValue(this.participantId, out var recordedaccesses); return(this.queue.RWLock.EnterLock <bool>(info.TransactionId, info.Priority, recordedaccesses, false, new Task <bool>(() => { // check if we expired while waiting if (!this.queue.RWLock.TryGetRecord(info.TransactionId, out TransactionRecord <OperationState> record)) { throw new OrleansCascadingAbortException(info.TransactionId.ToString()); } // merge the current clock into the transaction time stamp record.Timestamp = this.queue.Clock.MergeUtcNow(info.TimeStamp); // link to the latest state if (record.State == null) { this.queue.GetMostRecentState(out record.State, out record.SequenceNumber); } // if this is the first write, make a deep copy of the state if (!record.HasCopiedState) { record.State = this.copier.DeepCopy(record.State); record.SequenceNumber++; record.HasCopiedState = true; } if (logger.IsEnabled(LogLevel.Debug)) { logger.Debug($"update-lock write v{record.SequenceNumber} {record.TransactionId} {record.Timestamp:o}"); } // record this write in the transaction info data structure info.RecordWrite(this.participantId, record.Timestamp); // perform the write try { detectReentrancy = true; record.State.Operation = operation; return true; } finally { if (logger.IsEnabled(LogLevel.Trace)) { logger.Trace($"EndWrite {info} {record.TransactionId} {record.Timestamp}"); } detectReentrancy = false; } } ))); }
public Task Commit(ITransactionCommitOperation <IRemoteCommitService> operation) { return(this.committer.OnCommit(operation)); }