[hibernate-commits] Hibernate SVN: r14792 - core/branches/Branch_3_2_4_SP1_CP/src/org/hibernate/jdbc.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Fri Jun 20 13:47:48 EDT 2008


Author: steve.ebersole at jboss.com
Date: 2008-06-20 13:47:48 -0400 (Fri, 20 Jun 2008)
New Revision: 14792

Modified:
   core/branches/Branch_3_2_4_SP1_CP/src/org/hibernate/jdbc/AbstractBatcher.java
Log:
HHH-3006 : occasional infinite loop on JTA tx-timeout

Modified: core/branches/Branch_3_2_4_SP1_CP/src/org/hibernate/jdbc/AbstractBatcher.java
===================================================================
--- core/branches/Branch_3_2_4_SP1_CP/src/org/hibernate/jdbc/AbstractBatcher.java	2008-06-20 17:42:09 UTC (rev 14791)
+++ core/branches/Branch_3_2_4_SP1_CP/src/org/hibernate/jdbc/AbstractBatcher.java	2008-06-20 17:47:48 UTC (rev 14792)
@@ -8,6 +8,7 @@
 import java.sql.SQLException;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.ConcurrentModificationException;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -298,40 +299,62 @@
 			releasing = true;
 
 			try {
-				if (batchUpdate!=null) batchUpdate.close();
+				if ( batchUpdate != null ) {
+					batchUpdate.close();
+				}
 			}
-			catch (SQLException sqle) {
+			catch ( SQLException sqle ) {
 				//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;
-			batchUpdateSQL=null;
+			batchUpdate = null;
+			batchUpdateSQL = null;
 
 			Iterator iter = resultSetsToClose.iterator();
 			while ( iter.hasNext() ) {
 				try {
 					logCloseResults();
-					( (ResultSet) iter.next() ).close();
+					( ( ResultSet ) iter.next() ).close();
 				}
-				catch (SQLException e) {
+				catch ( SQLException e ) {
 					// 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) {
-					// sybase driver (jConnect) throwing NPE here in certain cases
-					log.warn("Could not close a JDBC result set", e);
+				catch ( ConcurrentModificationException e ) {
+					// this has been shown to happen occasionally in rare cases
+					// 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();
 
 			iter = statementsToClose.iterator();
 			while ( iter.hasNext() ) {
 				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
-					log.warn("Could not close a JDBC statement", e);
+					log.warn( "Could not close a JDBC statement", e );
 				}
 			}
 			statementsToClose.clear();




More information about the hibernate-commits mailing list