franciscojunior/Npgsql2 — pull request #8 by roji (2012-11-15 18:36:40+00:00)
Title: Scope without prepared transactions

Hey Francisco and Josh, sorry for disappearing, had some busy times at work.

Here's an attempt at a patch which would remove the dependency on prepared transactions when a connection is closed within a TransactionScope. I added a unit test which reproduced the problem on stock Postgres installations: SystemTransactionTests.SimpleTransactionScopeWithImplicitEnlist.

My general approach was to check whether a local (non-prepared) transaction is still active in the NpgsqlPromotableSinglePhaseNotification when Close() is called. If so, we enter the "postponingClose" state instead of actually closing. Then, when the local transaction is terminated (because of a commit, rollback or promote) the connection is notified and does the real close. There are a few more tweaks (Dispose and reopen after close) but it should be pretty straightforward.

Note that this takes care of the pattern:
using (var conn1 = new NpgsqlConnection(...) {
conn1.Open(); conn1.Close();
conn1.Open(); conn1.Close();
}

But does *not* take care of the pattern:
using (var conn1 = new NpgsqlConnection(connString1) { ... }
using (var conn2 = new NpgsqlConnection(connString1) { ... }
As Josh suggested, since I think that would require handling stuff at the pool. Maybe a second commit?

Anyway, let me know what you think...

Note that there are also two tiny build cleanup commits before the real one...