[jboss-jira] [JBoss JIRA] (AG-140) Connection leak caused by failed transaction integration

Dmitry Telegin (Jira) issues at jboss.org
Wed May 13 17:35:54 EDT 2020


     [ https://issues.redhat.com/browse/AG-140?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Dmitry Telegin updated AG-140:
------------------------------
    Description: 
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

  was:
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), but it shouldn't lead to connection leaks.

The compete PoC: https://github.com/dteleguin/agroal-connection-leak-poc



> 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
>
> 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



--
This message was sent by Atlassian Jira
(v7.13.8#713008)


More information about the jboss-jira mailing list