async Task DispatchUsingReceiveTransaction(TransportTransaction transportTransaction, IEnumerable <UnicastTransportOperation> operations, CancellationToken cancellationToken) { transportTransaction.TryGet(SettingsKeys.TransportTransactionSqlConnectionKey, out SqlConnection sqlTransportConnection); transportTransaction.TryGet(SettingsKeys.TransportTransactionSqlTransactionKey, out SqlTransaction sqlTransportTransaction); transportTransaction.TryGet(out Transaction ambientTransaction); if (ambientTransaction != null) { if (sqlTransportConnection == null) { using (var connection = await connectionFactory.OpenNewConnection(cancellationToken).ConfigureAwait(false)) { await Dispatch(operations, connection, null, cancellationToken).ConfigureAwait(false); } } else { await Dispatch(operations, sqlTransportConnection, null, cancellationToken).ConfigureAwait(false); } } else { await Dispatch(operations, sqlTransportConnection, sqlTransportTransaction, cancellationToken).ConfigureAwait(false); } }
static bool InReceiveWithNoTransactionMode(TransportTransaction transportTransaction) { SqlTransaction nativeTransaction; transportTransaction.TryGet(out nativeTransaction); Transaction ambientTransaction; transportTransaction.TryGet(out ambientTransaction); return(nativeTransaction == null && ambientTransaction == null); }
public Task <CompletableSynchronizedStorageSession> TryAdapt(TransportTransaction transportTransaction, ContextBag context) { Transaction ambientTransaction; if (!transportTransaction.TryGet(out ambientTransaction)) { return(EmptyResult); } var sessionFactoryImpl = sessionFactory as SessionFactoryImpl; if (sessionFactoryImpl == null) { throw new NotSupportedException("Overriding default implementation of ISessionFactory is not supported."); } CompletableSynchronizedStorageSession session = new NHibernateLazyAmbientTransactionSynchronizedStorageSession( connectionFactory: () => OpenConnection(sessionFactoryImpl, ambientTransaction), sessionFactory: conn => { var sessionBuilder = sessionFactory.WithOptions(); sessionBuilder.Connection(conn); return(sessionBuilder.OpenSession()); }); return(Task.FromResult(session)); }
static bool InReceiveWithNoTransactionMode(TransportTransaction transportTransaction) { transportTransaction.TryGet(SettingsKeys.TransportTransactionSqlTransactionKey, out SqlTransaction nativeTransaction); transportTransaction.TryGet(out Transaction ambientTransaction); return(nativeTransaction == null && ambientTransaction == null); }
public Task Dispatch(TransportOperations outgoingMessages, TransportTransaction transaction, ContextBag context) { InMemoryTransaction inMemoryTransaction = null; if (transaction.TryGet(out inMemoryTransaction)) { } foreach (var unicastTransportOperation in outgoingMessages.UnicastTransportOperations) { if (inMemoryTransaction != null && unicastTransportOperation.RequiredDispatchConsistency != DispatchConsistency.Isolated) { var x = unicastTransportOperation; inMemoryTransaction.Enlist(() => DispatchUnicastMessage(x)); } else { DispatchUnicastMessage(unicastTransportOperation); } } foreach (var multicastTransportOperation in outgoingMessages.MulticastTransportOperations) { if (inMemoryTransaction != null && multicastTransportOperation.RequiredDispatchConsistency != DispatchConsistency.Isolated) { inMemoryTransaction.Enlist(() => DispatchMulticastMessage(multicastTransportOperation)); } else { DispatchMulticastMessage(multicastTransportOperation); } } return(Task.CompletedTask); }
internal override async Task <StorageSession> TryAdaptTransportConnection( TransportTransaction transportTransaction, ContextBag context, IConnectionManager connectionManager, Func <DbConnection, DbTransaction, bool, StorageSession> storageSessionFactory, CancellationToken cancellationToken = default) { if (DoNotUseTransportConnection) { return(null); } // SQL server transport in native TX mode if (transportTransaction.TryGet("System.Data.SqlClient.SqlConnection", out DbConnection existingSqlConnection) && transportTransaction.TryGet("System.Data.SqlClient.SqlTransaction", out DbTransaction existingSqlTransaction)) { return(storageSessionFactory(existingSqlConnection, existingSqlTransaction, false)); } // 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 connectionManager.OpenConnection(context.GetIncomingMessage(), cancellationToken).ConfigureAwait(false); connection.EnlistTransaction(ambientTransaction); return(storageSessionFactory(connection, null, true)); }
static bool TryGetReceiveContext(TransportTransaction transportTransaction, out ReceiveContext receiveContext) { if (transportTransaction == null) { receiveContext = null; return(false); } return(transportTransaction.TryGet(out receiveContext)); }
public Task <CompletableSynchronizedStorageSession> TryAdapt(TransportTransaction transportTransaction, ContextBag context) { IEventStoreConnection connection; if (!transportTransaction.TryGet(out connection)) { throw new Exception("EventStore persistence can only be used with EventStore transport."); } return(Task.FromResult <CompletableSynchronizedStorageSession>(new EventStoreSynchronizedStorageSession(connection))); }
public async Task <CompletableSynchronizedStorageSession> TryAdapt(TransportTransaction transportTransaction, ContextBag context) { Transaction ambientTransaction; if (transportTransaction.TryGet(out ambientTransaction)) { NpgsqlConnection existingSqlConnection; //SQL server transport in ambient TX mode if (transportTransaction.TryGet(out existingSqlConnection)) { return(new StorageSession(existingSqlConnection, null)); } //Other transport in ambient TX mode var connection = await NpgSqlHelpers.NewConnection(_connectionString); return(new StorageSession(connection, connection.BeginTransaction())); } return(null); }
async Task DispatchIsolated(SortingResult sortedOperations, TransportTransaction transportTransaction, CancellationToken cancellationToken) { if (sortedOperations.IsolatedDispatch == null) { return; } transportTransaction.TryGet(SettingsKeys.IsUserProvidedTransactionKey, out bool userProvidedTransaction); if (userProvidedTransaction) { transportTransaction.TryGet(SettingsKeys.TransportTransactionSqlTransactionKey, out SqlTransaction sqlTransportTransaction); if (sqlTransportTransaction != null) { await Dispatch(sortedOperations.IsolatedDispatch, sqlTransportTransaction.Connection, sqlTransportTransaction, cancellationToken).ConfigureAwait(false); return; } transportTransaction.TryGet(SettingsKeys.TransportTransactionSqlConnectionKey, out SqlConnection sqlTransportConnection); if (sqlTransportConnection != null) { await Dispatch(sortedOperations.IsolatedDispatch, sqlTransportConnection, null, cancellationToken).ConfigureAwait(false); return; } throw new Exception($"Invalid {nameof(TransportTransaction)} state. Transaction provided by the user but contains no SqlTransaction or SqlConnection objects."); } using (var scope = new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled)) using (var connection = await connectionFactory.OpenNewConnection(cancellationToken).ConfigureAwait(false)) using (var tx = connection.BeginTransaction()) { await Dispatch(sortedOperations.IsolatedDispatch, connection, tx, cancellationToken).ConfigureAwait(false); tx.Commit(); scope.Complete(); } }
public Task <CompletableSynchronizedStorageSession> TryAdapt(TransportTransaction transportTransaction, ContextBag context) { Transaction ambientTransaction; if (transportTransaction.TryGet(out ambientTransaction)) { var session = context.GetSession(); CompletableSynchronizedStorageSession completableSynchronizedStorageSession = new MartenSynchronizedStorageSession(session, true); return(Task.FromResult(completableSynchronizedStorageSession)); } return(EmptyResult); }
async Task DispatchUsingReceiveTransaction(TransportTransaction transportTransaction, List <UnicastTransportOperation> operations) { SqlConnection sqlTransportConnection; SqlTransaction sqlTransportTransaction; Transaction ambientTransaction; transportTransaction.TryGet(out sqlTransportConnection); transportTransaction.TryGet(out sqlTransportTransaction); transportTransaction.TryGet(out ambientTransaction); if (ambientTransaction != null) { using (var connection = await connectionFactory.OpenNewConnection().ConfigureAwait(false)) { await Send(operations, connection, null).ConfigureAwait(false); } } else { await Send(operations, sqlTransportConnection, sqlTransportTransaction).ConfigureAwait(false); } }
public Task <CompletableSynchronizedStorageSession> TryAdapt(TransportTransaction transportTransaction, ContextBag context) { // ReSharper disable once NotAccessedVariable - No way to just check for existence otherwise Transaction ambientTransaction; if (transportTransaction.TryGet(out ambientTransaction)) { var session = context.GetAsyncSession(); CompletableSynchronizedStorageSession completableSynchronizedStorageSession = new RavenDBSynchronizedStorageSession(session, true); return(Task.FromResult(completableSynchronizedStorageSession)); } return(EmptyResult); }
public async Task Dispatch(TransportOperations outgoingMessages, TransportTransaction transportTransaction, ContextBag context) { IEventStoreConnection c; if (transportTransaction.TryGet(out c)) { await Dispatch(outgoingMessages, c).ConfigureAwait(false); } else { await Dispatch(outgoingMessages, sharedConnection).ConfigureAwait(false); } }
public Task <CompletableSynchronizedStorageSession> TryAdapt(TransportTransaction transportTransaction, ContextBag context) { Transaction ambientTransaction; if (transportTransaction.TryGet(out ambientTransaction)) { var transaction = new InMemoryTransaction(); CompletableSynchronizedStorageSession session = new InMemorySynchronizedStorageSession(transaction); ambientTransaction.EnlistVolatile(new EnlistmentNotification(transaction), EnlistmentOptions.None); return(Task.FromResult(session)); } return(EmptyTask); }
public Task<CompletableSynchronizedStorageSession> TryAdapt(TransportTransaction transportTransaction, ContextBag context) { Transaction ambientTransaction; if (transportTransaction.TryGet(out ambientTransaction)) { var transaction = new InMemoryTransaction(); CompletableSynchronizedStorageSession session = new InMemorySynchronizedStorageSession(transaction); ambientTransaction.EnlistVolatile(new EnlistmentNotification(transaction), EnlistmentOptions.None); return Task.FromResult(session); } return EmptyTask; }
public async Task <CompletableSynchronizedStorageSession> TryAdapt(TransportTransaction transportTransaction, ContextBag context) { SqlConnection existingSqlConnection; SqlTransaction existingSqlTransaction; //SQL server transport in native TX mode if (transportTransaction.TryGet(out existingSqlConnection) && transportTransaction.TryGet(out existingSqlTransaction)) { return(new StorageSession(existingSqlConnection, existingSqlTransaction, false, infoCache)); } // Transport supports DTC and uses TxScope owned by the transport Transaction transportTx; var scopeTx = Transaction.Current; if (transportTransaction.TryGet(out 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) { var connection = await connectionBuilder.OpenConnection().ConfigureAwait(false); connection.EnlistTransaction(ambientTransaction); return(new StorageSession(connection, null, true, infoCache)); } //Other modes handled by creating a new session. return(null); }
static bool TryGetNativeTransaction(TransportTransaction transportTransaction, out MessageQueueTransaction transaction) { return(transportTransaction.TryGet(out transaction)); }
public Task Dispatch(TransportOperations outgoingMessages, TransportTransaction transaction, CancellationToken cancellationToken = default) { // Assumption: we're not implementing batching as it will be done by ASB client transaction.TryGet <ServiceBusClient>(out var client); transaction.TryGet <string>("IncomingQueue.PartitionKey", out var partitionKey); transaction.TryGet <CommittableTransaction>(out var committableTransaction); var unicastTransportOperations = outgoingMessages.UnicastTransportOperations; var multicastTransportOperations = outgoingMessages.MulticastTransportOperations; var tasks = new List <Task>(unicastTransportOperations.Count + multicastTransportOperations.Count); foreach (var transportOperation in unicastTransportOperations) { var destination = transportOperation.Destination; // Workaround for reply-to address set by ASB transport var index = transportOperation.Destination.IndexOf('@'); if (index > 0) { destination = destination.Substring(0, index); } var sender = messageSenderPool.GetMessageSender(destination, client); try { var message = transportOperation.Message.ToAzureServiceBusMessage(transportOperation.Properties, partitionKey); ApplyCustomizationToOutgoingNativeMessage(transportOperation, message, transaction); var transactionToUse = transportOperation.RequiredDispatchConsistency == DispatchConsistency.Isolated ? null : committableTransaction; using (var scope = transactionToUse.ToScope()) { // Invoke sender and immediately return it back to the pool w/o awaiting for completion tasks.Add(sender.SendMessageAsync(message, cancellationToken)); //committable tx will not be committed because this scope is not the owner scope.Complete(); } } finally { messageSenderPool.ReturnMessageSender(sender, client); } } foreach (var transportOperation in multicastTransportOperations) { var sender = messageSenderPool.GetMessageSender(topicName, client); try { var message = transportOperation.Message.ToAzureServiceBusMessage(transportOperation.Properties, partitionKey); ApplyCustomizationToOutgoingNativeMessage(transportOperation, message, transaction); var transactionToUse = transportOperation.RequiredDispatchConsistency == DispatchConsistency.Isolated ? null : committableTransaction; using (var scope = transactionToUse.ToScope()) { // Invoke sender and immediately return it back to the pool w/o awaiting for completion tasks.Add(sender.SendMessageAsync(message, cancellationToken)); //committable tx will not be committed because this scope is not the owner scope.Complete(); } } finally { messageSenderPool.ReturnMessageSender(sender, client); } } return(tasks.Count == 1 ? tasks[0] : Task.WhenAll(tasks)); }
static bool InReceiveOnlyTransportTransactionMode(TransportTransaction transportTransaction) { return(transportTransaction.TryGet(ProcessWithNativeTransaction.ReceiveOnlyTransactionMode, out bool _)); }
public Task Dispatch(TransportOperations outgoingMessages, TransportTransaction transaction, ContextBag context) { // Assumption: we're not implementing batching as it will be done by ASB client var receiverConnectionAndPathFound = transaction.TryGet <(ServiceBusConnection, string)>(out var receiverConnectionAndPath); var partitionKeyFound = transaction.TryGet <string>("IncomingQueue.PartitionKey", out var partitionKey); var shouldSuppressTransaction = !(receiverConnectionAndPathFound && partitionKeyFound) && Transaction.Current != null; var unicastTransportOperations = outgoingMessages.UnicastTransportOperations; var multicastTransportOperations = outgoingMessages.MulticastTransportOperations; var tasks = new List <Task>(unicastTransportOperations.Count + multicastTransportOperations.Count); foreach (var transportOperation in unicastTransportOperations) { var destination = transportOperation.Destination; // Workaround for reply-to address set by ASB transport var index = transportOperation.Destination.IndexOf('@'); if (index > 0) { destination = destination.Substring(0, index); } var receiverConnectionAndPathToUse = transportOperation.RequiredDispatchConsistency == DispatchConsistency.Isolated ? (null, null) : receiverConnectionAndPath; var sender = messageSenderPool.GetMessageSender(destination, receiverConnectionAndPathToUse); try { var message = transportOperation.Message.ToAzureServiceBusMessage(transportOperation.DeliveryConstraints, partitionKey); using (var scope = CreateTransactionScope(transportOperation.RequiredDispatchConsistency, shouldSuppressTransaction)) { // Invoke sender and immediately return it back to the pool w/o awaiting for completion tasks.Add(sender.SendAsync(message)); scope?.Complete(); } } finally { messageSenderPool.ReturnMessageSender(sender); } } foreach (var transportOperation in multicastTransportOperations) { var receiverConnectionAndPathToUse = transportOperation.RequiredDispatchConsistency == DispatchConsistency.Isolated ? (null, null) : receiverConnectionAndPath; var sender = messageSenderPool.GetMessageSender(topicName, receiverConnectionAndPathToUse); try { var message = transportOperation.Message.ToAzureServiceBusMessage(transportOperation.DeliveryConstraints, partitionKey); using (var scope = CreateTransactionScope(transportOperation.RequiredDispatchConsistency, shouldSuppressTransaction)) { // Invoke sender and immediately return it back to the pool w/o awaiting for completion tasks.Add(sender.SendAsync(message)); scope?.Complete(); } } finally { messageSenderPool.ReturnMessageSender(sender); } } return(tasks.Count == 1 ? tasks[0] : Task.WhenAll(tasks)); }
static bool TryGetNativeTransaction(TransportTransaction transportTransaction, out MessageQueueTransaction transaction) { return transportTransaction.TryGet(out transaction); }