HHH-3006 : occansional infinite loop on JTA tx-timeout

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@14788 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Steve Ebersole 2008-06-19 16:23:58 +00:00
parent e3b572f2ee
commit 4bf13b7e9b

View File

@ -8,6 +8,7 @@
import java.sql.SQLException; import java.sql.SQLException;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.ConcurrentModificationException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -296,28 +297,45 @@ public void closeStatements() {
releasing = true; releasing = true;
try { try {
if (batchUpdate!=null) batchUpdate.close(); if ( batchUpdate != null ) {
batchUpdate.close();
}
} }
catch (SQLException sqle) { catch ( SQLException sqle ) {
//no big deal //no big deal
log.warn("Could not close a JDBC prepared statement", sqle); log.warn( "Could not close a JDBC prepared statement", sqle );
} }
batchUpdate=null; batchUpdate = null;
batchUpdateSQL=null; batchUpdateSQL = null;
Iterator iter = resultSetsToClose.iterator(); Iterator iter = resultSetsToClose.iterator();
while ( iter.hasNext() ) { while ( iter.hasNext() ) {
try { try {
logCloseResults(); logCloseResults();
( (ResultSet) iter.next() ).close(); ( ( ResultSet ) iter.next() ).close();
} }
catch (SQLException e) { catch ( SQLException e ) {
// no big deal // no big deal
log.warn("Could not close a JDBC result set", e); log.warn( "Could not close a JDBC result set", e );
} }
catch (Throwable e) { catch ( ConcurrentModificationException e ) {
// sybase driver (jConnect) throwing NPE here in certain cases // this has been shown to happen occasionally in rare cases
log.warn("Could not close a JDBC result set", e); // when using a transaction manager + transaction-timeout
// where the timeout calls back through Hibernate's
// registered transaction synchronization on a separate
// "reaping" thread. In cases where that reaping thread
// executes through this block at the same time the main
// application thread does we can get into situations where
// these CMEs occur. And though it is not "allowed" per-se,
// the end result without handling it specifically is infinite
// looping. So here, we simply break the loop
log.info( "encountered CME attempting to release batcher; assuming cause is tx-timeout scenario and ignoring" );
break;
}
catch ( Throwable e ) {
// sybase driver (jConnect) throwing NPE here in certain
// cases, but we'll just handle the general "unexpected" case
log.warn( "Could not close a JDBC result set", e );
} }
} }
resultSetsToClose.clear(); resultSetsToClose.clear();
@ -325,11 +343,16 @@ public void closeStatements() {
iter = statementsToClose.iterator(); iter = statementsToClose.iterator();
while ( iter.hasNext() ) { while ( iter.hasNext() ) {
try { try {
closeQueryStatement( (PreparedStatement) iter.next() ); closeQueryStatement( ( PreparedStatement ) iter.next() );
} }
catch (SQLException e) { catch ( ConcurrentModificationException e ) {
// see explanation above...
log.info( "encountered CME attempting to release batcher; assuming cause is tx-timeout scenario and ignoring" );
break;
}
catch ( SQLException e ) {
// no big deal // no big deal
log.warn("Could not close a JDBC statement", e); log.warn( "Could not close a JDBC statement", e );
} }
} }
statementsToClose.clear(); statementsToClose.clear();