Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Npgsql 3.2+ unnecessarily uses prepared transactions on Mono #1592
New transactions implementation (Npgsql 3.2+) uses prepared transactions on Mono when any other resource is enlisted in the same managed transaction. It happens for example when using managed transactions with Npgsql and NHibernate on Mono. On .NET framework it works fine.
I believe the reason is Mono calls
Npgsql 3.1 enlists as
Steps to reproduce
Run the following code on Mono:
Npgsql tries to use prepared transactions and throws if they are disabled (the default):
Further technical details
Npgsql version: 3.2.3
Just tested and it's the same. Mono transactions code has not really changed for years: https://github.com/mono/mono/blob/master/mcs/class/System.Transactions/System.Transactions/Transaction.cs
referenced this issue
Jul 3, 2017
Going back to
I think Npgsql should instead register itself as a
What causes this trouble to appear on Mono with NHibernate, not on .Net Framework, is likely the fact NHibernate currently enlist with option
This option causes the NHibernate resource to be prepared first. Then if only Npgsql remains, since it supports single phase commit, it is executed as single phase. Without that option, Npgsql may get prepared first or simultaneously (when distributed), but since another resource has not yet voted, it cannot go single phase and go through 2PC.
You should test with code similar to the one in #1625 if registering "Npgsql like resource" as a durable resource would allow it to go again through its single phase under Mono.
I didn't test it but based on the source code (https://github.com/mono/mono/blob/master/mcs/class/System.Transactions/System.Transactions/Transaction.cs#L378-L414) it should work. Mono should prepare/commit all volatile resources and single-phase commit a single durable resource (durable resources are treated similarly as