Exemplo n.º 1
0
            internal override async Task <StorageSession> TryAdaptTransportConnection(TransportTransaction transportTransaction, ContextBag context, IConnectionManager connectionBuilder, Func <DbConnection, DbTransaction, bool, StorageSession> storageSessionFactory)
            {
                // Transport supports DTC and uses TxScope owned by the transport
                var scopeTx = Transaction.Current;

                if (transportTransaction.TryGet(out Transaction transportTx) &&
                    scopeTx != null &&
                    transportTx != scopeTx)
                {
                    throw new Exception("A TransactionScope has been opened in the current context overriding the one created by the transport. "
                                        + "This setup can result in inconsistent data because operations done via connections enlisted in the context scope won't be committed "
                                        + "atomically with the receive transaction. To manually control the TransactionScope in the pipeline switch the transport transaction mode "
                                        + $"to values lower than '{nameof(TransportTransactionMode.TransactionScope)}'.");
                }
                var ambientTransaction = transportTx ?? scopeTx;

                if (ambientTransaction == null)
                {
                    //Other modes handled by creating a new session.
                    return(null);
                }

                var connection = await connectionBuilder.OpenConnection(context.GetIncomingMessage()).ConfigureAwait(false);

                connection.EnlistTransaction(ambientTransaction);
                return(storageSessionFactory(connection, null, true));
            }
    public async Task <OutboxTransaction> BeginTransaction(ContextBag context)
    {
        var connection = await connectionManager.OpenConnection(context.GetIncomingMessage()).ConfigureAwait(false);

        var transaction = connection.BeginTransaction();

        return(new SqlOutboxTransaction(transaction, connection));
    }
    public async Task <CompletableSynchronizedStorageSession> OpenSession(ContextBag contextBag)
    {
        var connection = await connectionManager.OpenConnection(contextBag.GetIncomingMessage()).ConfigureAwait(false);

        var transaction = connection.BeginTransaction();

        return(new StorageSession(connection, transaction, true, infoCache));
    }
Exemplo n.º 4
0
    public async Task Begin(ContextBag context)
    {
        var incomingMessage = context.GetIncomingMessage();

        Connection = await connectionManager.OpenConnection(incomingMessage).ConfigureAwait(false);

        Transaction = Connection.BeginTransaction();
        await concurrencyControlStrategy.Begin(incomingMessage.MessageId, Connection, Transaction).ConfigureAwait(false);
    }
    public async Task Begin(ContextBag context, CancellationToken cancellationToken = default)
    {
        var incomingMessage = context.GetIncomingMessage();

        Connection = await connectionManager.OpenConnection(incomingMessage, cancellationToken).ConfigureAwait(false);

        Connection.EnlistTransaction(ambientTransaction);
        await concurrencyControlStrategy.Begin(incomingMessage.MessageId, Connection, null, cancellationToken).ConfigureAwait(false);
    }
    public async Task <CompletableSynchronizedStorageSession> OpenSession(ContextBag contextBag, CancellationToken cancellationToken = default)
    {
        var connection = await connectionManager.OpenConnection(contextBag.GetIncomingMessage(), cancellationToken).ConfigureAwait(false);

        var transaction = connection.BeginTransaction();
        var session     = new StorageSession(connection, transaction, true, infoCache);

        currentSessionHolder?.SetCurrentSession(session);
        return(session);
    }
 public async Task SetAsDispatched(string messageId, ContextBag context)
 {
     using (var connection = await connectionManager.OpenConnection(context.GetIncomingMessage()).ConfigureAwait(false))
         using (var command = sqlDialect.CreateCommand(connection))
         {
             command.CommandText = outboxCommands.SetAsDispatched;
             command.AddParameter("MessageId", messageId);
             command.AddParameter("DispatchedAt", DateTime.UtcNow);
             await command.ExecuteNonQueryEx().ConfigureAwait(false);
         }
 }
Exemplo n.º 8
0
    public async Task Begin(ContextBag context)
    {
        transactionScope   = new TransactionScope(TransactionScopeOption.RequiresNew, TransactionScopeAsyncFlowOption.Enabled);
        ambientTransaction = System.Transactions.Transaction.Current;
        var incomingMessage = context.GetIncomingMessage();

        Connection = await connectionManager.OpenConnection(incomingMessage).ConfigureAwait(false);

        Connection.EnlistTransaction(ambientTransaction);
        await concurrencyControlStrategy.Begin(incomingMessage.MessageId, Connection, null).ConfigureAwait(false);
    }
    public async Task <OutboxMessage> Get(string messageId, ContextBag context, CancellationToken cancellationToken = default)
    {
        using (new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled))
            using (var connection = await connectionManager.OpenConnection(context.GetIncomingMessage(), cancellationToken).ConfigureAwait(false))
                using (var transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted))
                {
                    OutboxMessage result;
                    using (var command = sqlDialect.CreateCommand(connection))
                    {
                        command.CommandText = outboxCommands.Get;
                        command.Transaction = transaction;
                        command.AddParameter("MessageId", messageId);

                        // to avoid loading into memory SequentialAccess is required which means each fields needs to be accessed, but SequentialAccess is unsupported for SQL Server AlwaysEncrypted
                        using (var dataReader = await command.ExecuteReaderAsync(CommandBehavior.SequentialAccess | CommandBehavior.SingleRow, cancellationToken).ConfigureAwait(false))
                        {
                            if (!await dataReader.ReadAsync(cancellationToken).ConfigureAwait(false))
                            {
                                return(null);
                            }
                            var dispatched = await dataReader.GetBoolAsync(0, cancellationToken).ConfigureAwait(false);

                            using (var textReader = dataReader.GetTextReader(1))
                            {
                                if (dispatched)
                                {
                                    result = new OutboxMessage(messageId, new TransportOperation[0]);
                                }
                                else
                                {
                                    var transportOperations = Serializer.Deserialize <IEnumerable <SerializableOperation> >(textReader)
                                                              .FromSerializable()
                                                              .ToArray();
                                    result = new OutboxMessage(messageId, transportOperations);
                                }
                            }
                        }
                    }
                    transaction.Commit();
                    return(result);
                }
    }