/// <inheritdoc />
        public async Task AppendToStream(string stream, int expectedVersion, UncommittedMessages data, CancellationToken token = default(CancellationToken))
        {
            Guard.StreamName(stream, nameof(stream));

            if (expectedVersion < ExpectedVersion.Any)
            {
                throw new ArgumentException("Expected version must be greater or equal 1, or 'Any', or 'NoStream'.", nameof(expectedVersion));
            }
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            try
            {
                switch (expectedVersion)
                {
                default:
                    _settings.Logger.Trace("Appending {0} messages to stream '{1}' with expected version {2}...", data.Messages.Length, stream, expectedVersion);
                    await AppendToStreamWithExpectedVersion(stream, expectedVersion, data, token).NotOnCapturedContext();

                    break;

                case ExpectedVersion.Any:
                    _settings.Logger.Trace("Appending {0} messages to stream '{1}' with any version...", data.Messages.Length, stream);
                    await AppendToStreamWithAnyVersion(stream, data, token).NotOnCapturedContext();

                    break;

                case ExpectedVersion.NoStream:
                    _settings.Logger.Trace("Appending {0} messages to stream '{1}' where stream not existed yet...", data.Messages.Length, stream);
                    await AppendToStreamWithExpectedVersion(stream, ExpectedVersion.NoStream, data, token).NotOnCapturedContext();

                    break;
                }

                _settings.Linearizer?.Start();
            }
            catch (WrongExpectedVersionException)
            {
                throw;
            }
            catch (Exception e)
            {
                _settings.Logger.Error(e.ToString());
            }
        }
        private async Task AppendToStreamWithAnyVersion(string stream, UncommittedMessages data, CancellationToken token)
        {
            _settings.Logger.Trace("Appending {0} messages to stream '{1}' with any version...", data.Messages.Length, stream);

            using (var connection = new SqlConnection(_settings.ConnectionString))
            {
                await connection.OpenAsync(token).NotOnCapturedContext();

                using (var tran = connection.BeginTransaction(IsolationLevel.ReadCommitted))
                {
                    try
                    {
                        foreach (var msg in data.Messages)
                        {
                            using (var cmd = connection.CreateCommandToAppendingWithAnyVersion(stream, data, msg))
                            {
                                cmd.Transaction = tran;
                                await cmd.ExecuteNonQueryAsync(token).NotOnCapturedContext();
                            }
                        }

                        tran.Commit();
                    }
                    catch (SqlException e)
                    {
                        tran.Rollback();

                        if (e.IsUniqueConstraintViolation() || e.IsWrongExpectedVersionRised())
                        {
                            throw new WrongExpectedVersionException($"Appending {data.Messages.Length} messages to stream '{stream}' with any version failed.", e);
                        }

                        throw;
                    }
                }
            }
        }
Beispiel #3
0
 private static async Task ReadingExecute(UncommittedMessages data)
 {
     await store.ReadStreamForward(data.CorrelationId.ToString(), 0);
 }
Beispiel #4
0
 private static async Task AppendingExecute(UncommittedMessages data)
 {
     await store.AppendToStream(data.CorrelationId.ToString(), ExpectedVersion.NoStream, data).NotOnCapturedContext();
 }
        private async Task AppendToStreamWithExpectedVersion(string stream, int expectedVersion, UncommittedMessages data, CancellationToken token)
        {
            using (var connection = new SqlConnection(_settings.ConnectionString))
            {
                await connection.OpenAsync(token).NotOnCapturedContext();

                using (var tran = connection.BeginTransaction(IsolationLevel.ReadCommitted))
                {
                    try
                    {
                        var messageVersion = expectedVersion;
                        foreach (var msg in data.Messages)
                        {
                            messageVersion += 1;
                            using (var cmd = expectedVersion == 0 && messageVersion == 1
                                ? connection.CreateCommandToAppendingWithNoStream(stream, data, msg)
                                : connection.CreateCommandToAppendingWithExpectedVersion(stream, data, msg, messageVersion))
                            {
                                cmd.Transaction = tran;
                                await cmd.ExecuteNonQueryAsync(token).NotOnCapturedContext();
                            }
                        }

                        tran.Commit();
                    }
                    catch (SqlException e)
                    {
                        tran.Rollback();

                        if (e.IsUniqueConstraintViolation() || e.IsWrongExpectedVersionRised())
                        {
                            throw new WrongExpectedVersionException($"Appending {data.Messages.Length} messages to stream '{stream}' with expected version {ExpectedVersion.Parse(expectedVersion)} failed.", e);
                        }

                        throw;
                    }
                }
            }
        }
        public static SqlCommand CreateCommandToAppendingWithNoStream(this SqlConnection cnn, string name, UncommittedMessages data, MessageRecord msg)
        {
            Guard.StreamName(msg.ContractName, "contractName");

            return(cnn
                   .CreateCommand(mantaAppendNoStreamCommand)
                   .AddInputParam(paramStreamName, SqlDbType.VarChar, name, SqlClientExtensions.DefaultStreamNameLength)
                   .AddInputParam(paramCorrelationId, SqlDbType.UniqueIdentifier, data.CorrelationId)
                   .AddInputParam(paramContractName, SqlDbType.VarChar, msg.ContractName, SqlClientExtensions.DefaultContractNameLength)
                   .AddInputParam(paramMessageId, SqlDbType.UniqueIdentifier, msg.MessageId)
                   .AddInputParam(paramPayload, SqlDbType.VarBinary, msg.Payload)
                   .AddInputParam(paramMetadataPayload, SqlDbType.VarBinary, data.Metadata));
        }