I am using Entity Framework Core with PostgreSQL. I want to override SaveChanges in my DbContext to both commit the EF changes and send a message with Rebus within the same database transaction. The plan is to also use PostgreSQL for transport etc, but I am having trouble merely enlisting Rebus in a transaction scope using the code below.
public override int SaveChanges()
{
using (var tx = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
tx.EnlistRebus();
var result = base.SaveChanges();
//TODO: _bus.Send("something happened");
tx.Complete();
return result;
}
}
Running the above results in PostgresException: 55000: prepared transactions are disabled, which is true, since my PostgreSQL configuration has not enabled it. My question is why Rebus needs to cause a 2-phase commit here. Maybe I'm missing something, though I would hope a 2PC is not needed, given both Entity Framework and Rebus will use the same relational database instance.
The call to EnlistRebus is in the Rebus.TransactionScopes package and does not know what transport implementation is in use and might do the safe thing.
Is there another way to do both the database operation and Rebus send transactionally without 2-phase commit? I can of course use a separate table to store my pending message from SaveChanges and have a separate worker pull from that table and send the message using Rebus. I suspect this approach is the most solid and straightforward.
I am using Rebus 6.3.0, Rebus.PostgreAql 7.1.0, Rebus.TransactionScopes 6.0.0, Npgsql 4.1.3.1, Npgsql.EntityframeworkCore.PostgreSQL 3.1.4 and EF Core 3.1.4.