[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-4808) SessionImpl.initializeCollection() does not release JDBC connection (if outside of a transaction)

Martin Rexa (JIRA) noreply at atlassian.com
Thu Apr 5 12:12:48 EDT 2012


    [ https://hibernate.onjira.com/browse/HHH-4808?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=46196#comment-46196 ] 

Martin Rexa commented on HHH-4808:
----------------------------------

This issue is a big problem for using net.sf.ehcache.constructs.blocking.BlockingCache in hibernate since it can cause a deadlock if the amount of threads is much higher then the maximum size of connection pool.

Scenario leading to the deadlock:
Thread 1 comes to BlockingCache.get and gets a lock for particular key. This thread must reach BlockingCache.put, otherwise particular key stays locked and will block other threads trying to get the same key. Before calling BlockingCache.put the thread must construct the value which requires DB connection. Other threads are doing their job and at some point they reach BlockingCache.get for the same key which Thread 1 is trying to construct and are stopped by the lock. But because of this bug it could be that last DB operation they did was lazy loading and therefore these threads are holding DB connection. If the amount of these threads becomes the same as the maximum size of connection pool, we have a deadlock, since Thread 1 will never get connection needed to unblock other threads holding it.

> SessionImpl.initializeCollection() does not release JDBC connection (if outside of a transaction)
> -------------------------------------------------------------------------------------------------
>
>                 Key: HHH-4808
>                 URL: https://hibernate.onjira.com/browse/HHH-4808
>             Project: Hibernate ORM
>          Issue Type: Bug
>          Components: core
>    Affects Versions: 3.2.7, 3.3.2
>            Reporter: Martin Renner
>            Priority: Critical
>         Attachments: Test.java
>
>
> With {{ConnectionReleaseMode.AFTER_TRANSACTION}} (the default), Hibernate does not release the JDBC connection when resolving a lazily loaded collection, if this happens *outside* of an active transaction.
> First, I will describe, what happens if Hibernate executes a query outside of a transaction. Then I will describe how lazy collection loading behaves differently.
> When the method {{list}} of a query ({{QueryImpl.java}}) is getting called, Hibernate delegates to {{SessionImpl.list()}}. After having loaded the list, {{SessionImpl.list()}} calls {{SessionImpl.afterOperation()}}, which calls {{jdbcContext.afterNontransactionalQuery()}} (as there is no active transaction). This leads to {{ConnectionManager.afterTransaction()}} which releases the JDBC connection. This is exactly what I expect to happen.
> Now to the lazily loaded collection:
> {{Hibernate.initialize(collection)}} and {{person.getPets().size()}} both end up in {{SessionImpl.initializeCollection()}}. This call gets dispatched down to {{Loader.doQueryAndInitializeNonLazyCollections()}} and {{Loader.doQuery()}}. The important fact is, that {{ConnectionManager.afterTransaction()}} never gets called (like in the query-example above).
> The result is, that the JDBC connection is not released.
> IMHO resolving of a lazily loaded collection should behave like executing a query. {{SessionImpl.initializeCollection()}} should call {{SessionImpl.afterOperation()}} in the same way as {{SessionImpl.list()}} is doing this.
> I will attach a small demo application which shows the difference (concerning {{ConnectionManager}}) between queries and collections.

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        


More information about the hibernate-issues mailing list