public void AddState(string dataProviderKey, JToken data, Guid transactionId) { var dataStr = JsonConvert.SerializeObject(data, Formatting.Indented, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All }); TransactionStateEntity n = new TransactionStateEntity() { Data = dataStr, Id = transactionId }; var transactionalCasDataProvider = this.dataProviderPool.GetProvider(dataProviderKey); using (new StopwatchLog(Metrics.CassAdd)) { transactionalCasDataProvider.Mapper.InsertAsync(n, CqlQueryOptions.New()); } }
public async Task <string> Store(string expectedETag, TransactionalStateMetaData metadata, List <PendingTransactionState <TState> > statesToPrepare, long?commitUpTo, long?abortAfter) { if (_metadata.ETag != expectedETag) { throw new ArgumentException(nameof(expectedETag), "Etag does not match"); } var stateUpdater = new StateUpdater(_dbExecuter, _stateId, _options.StateTableName, _jsonSettings); // first, clean up aborted records if (abortAfter.HasValue && _states.Count != 0) { await stateUpdater.DeleteStates(afterSequenceId : abortAfter); while (_states.Count > 0 && _states[_states.Count - 1].SequenceId > abortAfter) { _states.RemoveAt(_states.Count - 1); } } // second, persist non-obsolete prepare records var obsoleteBefore = commitUpTo.HasValue ? commitUpTo.Value : _metadata.CommittedSequenceId; if (statesToPrepare != null && statesToPrepare.Count > 0) { foreach (var s in statesToPrepare) { if (s.SequenceId >= obsoleteBefore) { var newState = new TransactionStateEntity { SequenceId = s.SequenceId, TransactionId = s.TransactionId, Timestamp = s.TimeStamp, TransactionManager = s.TransactionManager, Value = s.State }; if (FindState(s.SequenceId, out var pos)) { // overwrite with new pending state _states[pos] = newState; await stateUpdater.UpdateState(newState).ConfigureAwait(false); } else { await stateUpdater.InsertState(newState).ConfigureAwait(false); _states.Insert(pos, newState); } _logger.LogTrace($"{_stateId}.{newState.SequenceId} Update {newState.TransactionId}"); } } } await stateUpdater.EnsureInsertBufferFlushed(); // third, persist metadata and commit position _metadata = await PersistMetadata(metadata, commitUpTo ?? _metadata.CommittedSequenceId); // fourth, remove obsolete records if (_states.Count > 0 && _states[0].SequenceId < obsoleteBefore) { FindState(obsoleteBefore, out var pos); await stateUpdater.DeleteStates(beforeSequenceId : obsoleteBefore); _states.RemoveRange(0, pos); } return(_metadata.ETag); }