Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pool should not yield a connection with an ongoing transaction [DNET793] #731

Open
firebird-automations opened this issue Oct 24, 2017 · 1 comment

Comments

@firebird-automations
Copy link

Submitted by: Frédéric Delaporte (fredericdelaporte)

In distributed transaction cases, the transaction completion occurs asynchronously and concurrently to code following the transaction scope disposal.

In such case, it is possible to release the connection to the pool while its transaction is still ongoing, without having any clue about that. And requesting a connection from pool may then yield a connection still having an ongoing transaction.
Trying to begin a new transaction on it then fails with error: System.InvalidOperationException : A transaction is currently active. Parallel transactions are not supported.

Granted, that is a wicked case.

See npgsql/npgsql#1571 (comment) discussion with a Microsoft employee: when distributed, MSDTC considers a transaction to be committed once it has collected all participant votes for committing from prepare phase. It then immediately notifies all participants of the outcome. This causes TransactionScope.Dispose to leave while the second phase of participants may still be executing. This means the transaction from the db view point can still be pending and not yet committed after the scope disposal. This is by design of MSDTC and we have to cope with that.
Some data provider may have a global locking mechanism causing any subsequent connection use to wait for the end of the commit phase, but this is not a general case. Such a mechanism has been put in place for NHibernate own volatile resource, but this only guarantee us that this NHibernate resource has ended its processing, it does not guarantee us that is the case of the Firebird one.

This causes a number of NHibernate tests to fail with Firebird regularly but not consistently.

A test case pattern for this would likely be like the [DistributedRollback|https://github\.com/npgsql/npgsql/blob/dev/test/Npgsql\.Tests/SystemTransactionTests\.cs#⁠L204\] test of Npgsql. There are more wicked cases involving distributed transaction in this test file, it may be worth checking them with Firebird too.
(For information, Npgsql checks distributed transaction status on connection when closed for avoiding returning them to pool if the transaction is not ended, something like just flagging them as having to return to pool once their transaction completion event finally gets executed. This avoid at least the pool trouble but not some other issues like trying to reuse the same connection immediately after a distributed scope disposal.)

@firebird-automations
Copy link
Author

Commented by: Frédéric Delaporte (fredericdelaporte)

It was indeed tested with 6.0.0-Alpha2 version of Firebird .Net Data provider.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants