6 years later, but I hope this can help future readers.
Background
For a couple of years, we have encountered a production bug that kept exhausting the pooled connection in an Atomikos managed Hibernate (3.x.x) & JTA integration.
With our Atomikos "recovery strategy" (i.e. force release all connections), this was fine until recent upscale with direct modern collaborators with multiple instances in K8S pushed the app's tipping point where we needed to address this issue.
Navigating around, I found the following set:
setProperty("hibernate.connection.release_mode", "after_transaction");
Which after research it led me to this question (and other multiple unclear/unanswered questions regarding this mode)
So here are the findings:
Origin of Flag
In 2005, it seems that a Hibernate JTA integration was causing issues, as a result HHH-1287 was raised:
It looks like the ExtendedJTATransaction is simply not available after the CMT completes and the WebSphereExtendedJTATransactionLookup class attempts to look it up at java:comp/websphere/ExtendedJTATransaction as part of the normal 'after completion' callback.
The problem occurs when the afterCompletion callback event fires and the ConnectionManager.isAggressiveRelease() method is called from ConnectionManager.afterTransaction(). This attempts to check to see if a transaction is in progress. This test in fact causes the transaction manager to be created (together with a look up of the current transaction) The lookup of the ExtendedJTATransaction fails and the an exception is thrown (see stack trace below).
Although there may be an inconsistency in the way that a SSB and MDB operate, It seems fair to say that the transaction may not be available if it has completed. A workaround is therefore requested.
As a result a change was committed to circumvent the JTA transaction check in this scenario in the connection manager: (This has then gone though further improvements)
private boolean isAggressiveReleaseNoTransactionCheck() {
if (releaseMode == ConnectionReleaseMode.AFTER_STATEMENT) {
return true;
}
else {
boolean inAutoCommitState;
try {
inAutoCommitState = isAutoCommit();
}
catch( SQLException e ) {
inAutoCommitState=true; // assume we are in an auto-commit state
}
return releaseMode == ConnectionReleaseMode.AFTER_TRANSACTION && inAutoCommitState;
}
}
Feature Release
After verifying this works, it was released in the wild with the following documentation for 3.x.x:
Table 3.4. Hibernate JDBC and Connection Properties
Property name |
Purpose |
hibernate.connection.release_mode |
Specify when Hibernate should release JDBC connections. By default, a JDBC connection is held until the session is explicitly closed or disconnected. For an application server JTA datasource, you should use after_statement to aggressively release connections after every JDBC call. For a non-JTA connection, it often makes sense to release the connection at the end of each transaction, by using after_transaction . auto will choose after_statement for the JTA and CMT transaction strategies and after_transaction for the JDBC transaction strategy. eg. auto (default) / on_close / after_transaction / after_statement |
For an application server JTA datasource, you should use after_statement
to aggressively release connections after every JDBC call.
Given conclusion
Therefore, this was work around certain containers (not just EE containers) that implement "resource containment" checks.
The Hibernate Session defers getting a JDBC Connection until it actually needs one, which can lead to cases like the following where 2 beans share a Session/EM:
- Bean1: get Session, but don't use it yet in way that needs Connection
- Bean1: call Bean2...
- Bean2: get Session, do some work forcing Session to obtain Connection
- Bean2: return (Session still hold Connection)
At this point, these containers see this as a "leaked" Connection because the handle was not released by the end of the scope in which it was obtained. Hence, aggressive releasing.
You can read more about this in detail here: [hibernate-dev] - Connection release modes
Useful References and Resources: