I am migrating from using MSMQ to Amazon SQS. I’ve enabled the outbox to help ensure that messages are delivered only once. In many of the MessageHandlers, I make a MediatR request when a message is received. I’ve configured the outbox with UseTransactionScope
so that if an exception is thrown after the MediatR request completes but before the MessageHandler completes, any database modifications will be rolled back.
Currently a unit of work is opened in the MediatR pipeline (which also creates its own NHibernate SessionFactory). With MSMQ and MSDTC, this works just fine. With the new SQS implementation, I get multiple transaction-related errors such as:
System transaction prepare phase failed - NHibernate.Transaction.ITransactionFactory
System.Transactions.TransactionInDoubtException: The transaction is in doubt.
System.Data.SqlClient.SqlException: Execution Timeout Expired.
System.InvalidOperationException: The operation is not valid for the current state of the enlistment.
In the logs I see that two NHibernate SessionFactories are created, one by my MediatR pipeline and one by NServiceBus (using NHibernatePersistence). I assumed that enabling UseTransactionScope
on the Outbox would allow the same transaction to be shared, but based on the error messages I would guess one of the sessions is unable to enlist in the transaction started by the other session. But I don’t understand why or what to do about it.
The IsolationLevel for both session factories is set to ReadCommitted, so I would think the transaction should be compatible for both sessions.
What should I do?