Connection leak caused by failed transaction integration
--------------------------------------------------------
Key: AG-140
URL:
https://issues.redhat.com/browse/AG-140
Project: Agroal
Issue Type: Bug
Components: narayana, pool
Affects Versions: 1.8
Reporter: Dmitry Telegin
Assignee: Luis Barreiro
Priority: Major
Fix For: 1.9
Attachments: agroal-connection-leak-poc.log
If the following conditions are met:
- transaction integration is installed;
- connection checkout has been successful;
- {{transactionIntegration.associate(...)}} (ConnectionPool.java:222) throws an
exception,
then the code that called {{getConnection()}} will have no reference to the connection
object, hence no ability to close it and return to the pool. The connection won't be
reaped or GCed, thus staying in the checked-out state forever, which in turn can lead to
connection pool exhaustion.
The following snippet demonstrates the issue (assuming that Hibernate uses
Agroal+Narayana and the transaction is active):
{code:java}
Foo foo = new Foo();
try {
em.merge(foo); // org.hibernate.id.IdentifierGenerationException due to
missing ID, transaction aborted
} catch (Exception e) {
// suppress exception
LOG.log(Level.WARNING, "merge", e);
}
// continue using the same EntityManager
em.find(Foo.class, 0L); // java.sql.SQLException: Exception in association of
connection to existing transaction, connection leaked
{code}
Obviously, the usage pattern is invalid (must handle the exception properly and must not
use EntityManager afterwards), but it shouldn't lead to connection leaks either.
The compete PoC:
https://github.com/dteleguin/agroal-connection-leak-poc