Hi,
I have a problem detecting the deadlock situation in Hibernate.
To retry a select when a deadlock happens I need to detect a specific SQLException with ErrorCode=1205 in Sybase.
When running Hbernate the deadlock exception is logged by JDBCExceptionReporter but not thrown back to the client. Instead a different SQLException "JZ0EM: End of data" happens when net.sf.hibernate.loader.Loader.doQuery() closes resultset in finally clause. This exception gets thrown instead of original exception.
Is there a way to get the original Exception?
Thank you very much.
Hibernate version: 2.1.4
Client code:
protected List tryToList(Query q, String hql) throws Exception {
for (int trial = 0; ; trial++) {
try {
return q.list();
}
catch (Throwable t) {
if (t instanceof JDBCException) {
int err = ( (JDBCException) t).getErrorCode();
if ( err == orion.db.ORDBUtil.DEADLOCK &&
trial < DEADLOCK_MAX_TRIALS) {
log.warn("Deadlock detected... for hql:\n " + hql);
try {
long sleepTime = (long) (Math.random() * DEADLOCK_SLEEP_MILLIS);
log.info("Sleeping..." + sleepTime);
Thread.sleep(sleepTime);
}
catch (Exception ex) {
}
continue;
}
}
else {
Exception ex = new Exception("@ " + hql, t);
ex.setStackTrace(new StackTraceElement[] {});
throw ex;
}
}
}
}
Full stack trace of any exception that occurs:
2004-12-12 18:48:11,669 ExecuteThread: '15' for queue: 'weblogic.kernel.Default' WARN net.sf.hibernate.util.JDBCExceptionRepor
ter - SQL Error: 1205, SQLState: 40001
2004-12-12 18:48:11,669 ExecuteThread: '15' for queue: 'weblogic.kernel.Default' WARN net.sf.hibernate.util.JDBCExceptionRepor
ter - SQL Error: 1205, SQLState: 40001
2004-12-12 18:48:11,669 ExecuteThread: '15' for queue: 'weblogic.kernel.Default' ERROR net.sf.hibernate.util.JDBCExceptionRepo
rter - Your server command (family id #0, process id #441) encountered a deadlock situation. Please re-run your command.
2004-12-12 18:48:11,671 ExecuteThread: '15' for queue: 'weblogic.kernel.Default' WARN net.sf.hibernate.util.JDBCExceptionRepor
ter - SQL Error: 0, SQLState: JZ006
ter - SQL Error: 0, SQLState: JZ006
2004-12-12 18:48:11,671 ExecuteThread: '15' for queue: 'weblogic.kernel.Default' ERROR net.sf.hibernate.util.JDBCExceptionRepo
rter - JZ006: Caught IOException: java.io.IOException: JZ0EM: End of data.2004-12-12 18:48:11,676 ExecuteThread: '15' for queue: 'weblogic.kernel.Default' ERROR net.sf.hibernate.util.JDBCExceptionRepo
rter - Could not execute query
java.sql.SQLException: JZ006: Caught IOException: java.io.IOException: JZ0EM: End of data.
at com.sybase.jdbc2.jdbc.ErrorMessage.raiseError(ErrorMessage.java:493)
at com.sybase.jdbc2.jdbc.ErrorMessage.raiseErrorCheckDead(ErrorMessage.java:729)
at com.sybase.jdbc2.tds.TdsResultSet.next(TdsResultSet.java:292)
at com.sybase.jdbc2.tds.TdsResultSet.close(TdsResultSet.java:392)
at com.sybase.jdbc2.jdbc.SybResultSet.markDead(SybResultSet.java:1507)
at com.sybase.jdbc2.jdbc.SybResultSet.close(SybResultSet.java:1565)
at com.sybase.jdbc2.jdbc.SybResultSet.close(SybResultSet.java:182)
at weblogic.jdbc.wrapper.ResultSet.internalClose(ResultSet.java:111)
at weblogic.jdbc.wrapper.ResultSet.close(ResultSet.java:150)
at net.sf.hibernate.impl.BatcherImpl.closeQueryStatement(BatcherImpl.java:99)
at net.sf.hibernate.loader.Loader.doQuery(Loader.java:234)
at net.sf.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:133)
at net.sf.hibernate.loader.Loader.doList(Loader.java:955)
at net.sf.hibernate.loader.Loader.list(Loader.java:946)
at net.sf.hibernate.hql.QueryTranslator.list(QueryTranslator.java:846)
at net.sf.hibernate.impl.SessionImpl.find(SessionImpl.java:1543)
at net.sf.hibernate.impl.QueryImpl.list(QueryImpl.java:39)
at orion.dao.hibernate.HibDAO.tryToList(HibDAO.java:139)
Name and version of the database you are using: Sybase ASE 12.5
|