Skip to Main Content

Java Database Connectivity (JDBC)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Exception and Statement's cancel()-method

5295Feb 12 2003
Hi,

I've written an object which is responsible for running and cancelling SQL-Statements. These are normally Statements which last quite a long time. So we gave the user the ability to cancel the execution, if he don't want to wait any longer. All works fine. But in some rare cases I get Exceptions
, at lines I didn't expect to get them.
Maybe anybody out there could give me a hint, what I'm missing:

1) Within the cancel()-method I get the following Exception at the line
_stmt.close();

java.sql.SQLException: ORA-01013: user requested cancel of current operation

at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:168)
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:208)
at oracle.jdbc.ttc7.Oclose.receive(Oclose.java:126)
at oracle.jdbc.ttc7.TTC7Protocol.close(TTC7Protocol.java:533)
at oracle.jdbc.driver.OracleStatement.close(OracleStatement.java:595)
at com.airplus.aim.bericht.auswertung.AbstractAuswertung$1.run(AbstractAuswertung.java:210)


2) Within the execute()-method I get the following Exception at the line
while (_rs.next()) {
java.sql.SQLException: Closed Statement: next
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:168)
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:210)
at oracle.jdbc.dbaccess.DBError.check_error(DBError.java:829)
at oracle.jdbc.driver.OracleResultSetImpl.next(OracleResultSetImpl.java:191)
at com.airplus.aim.bericht.auswertung.AbstractAuswertung.execute(AbstractAuswertung.java:425)

Because of all the synchronization I didn't expect any of these Exceptions at these lines.

Any help would be great.

Harald

Environment:
Oracle RDBMS 8.1.7
Oracle JDBC Thin Driver 8.1.7

Source-Code( fragment, not compile clean):

package com.airplus.aim.bericht.auswertung;

import java.util.List;
import java.util.Locale;
import java.util.Vector;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.ResultSet;

import com.airplus.aim.bericht.DataNotFoundException;
import com.airplus.aim.datenbank.implementierung.AimPoolProxy;
import com.airplus.aim.bericht.IAuswertung;
import com.airplus.aim.bericht.IZeile;
import com.airplus.aim.bericht.IBerichtsdefinition;
import com.airplus.aim.bericht.IErgebnis;
import com.airplus.aim.bericht.DefaultErgebnis;
import com.airplus.aim.bericht.QueryCancelledException;
import com.airplus.aim.bericht.QueryTimeOutException;
import com.airplus.aim.util.SystemConstants;



public abstract class AbstractAuswertung implements IAuswertung {

private DataSource _connPool = AimPoolProxy.getInstance();
private Connection _conn = null;
private Statement _stmt = null;
private ResultSet _rs = null;

private DefaultErgebnis _erg = new DefaultErgebnis();
private StringBuffer _sqlText = new StringBuffer("Long running SELECT");

/**
* distinquish between "user Cancel" and "query timeout"
*/
private boolean userCanceled = false;

/**
* Der Lock für die "Cancel"-Operation, damit das Abbrechen des Statements
* mit dem Auslesen daraus synchronisiert wird.
*/
private Boolean cancelLock = Boolean.TRUE;

public AbstractAuswertung() {

}

/**
cancel the current Statement
*/
public final boolean cancel() {
Thread ath = new Thread() { // Beginn Thread-Implementierung
public void run() { // run-Methode des Threads
if (_stmt != null) { // 1
// synchronization with execute()
synchronized (cancelLock) { // 2
if (_stmt != null) { // 3
// indicate "user cancel"
userCanceled = true;
try {
_stmt.cancel();
if (_rs != null) {
_rs.close();
_rs = null;
}
_stmt.close();
}
catch (SQLException ex) {
_rs = null;
CtxLogMgr.getContextCategory().debug("Statement konnte nicht abgebrochen werden", ex);
}
_stmt = null;
} //3
} // 2
} // 1
} // run-Methode des Threads
}; // Ende Thread-Implementierung
ath.start();
return true;
}


public final synchronized IErgebnis execute(IBerichtsdefinition definition)
throws SQLException,
DataNotFoundException,
QueryCancelledException {
try {

// Connection holen
conn = connPool.getConnection();

if (_conn == null)
throw new SQLException("Connection is not available");
stmt = conn.createStatement();
if (_stmt == null)
throw new SQLException("Statement is not available");

// normally _sqlText is generated dynamically here

// set Timeout from config-file
String timeout = SystemConstants.AIMSYSTEM_CONF.getString("com.airplus.aim.db.QueryTimeOutMinutes");
try {
_stmt.setQueryTimeout(Integer.parseInt(timeout) * 60);

}
catch (NumberFormatException ne) {
_stmt.setQueryTimeout(10*60);
}

rs = stmt.executeQuery(_sqlText.toString());

if (_rs == null)
throw new SQLException("Result is not available");

// synchronization with cancel()
// the statement should not be canceled, if we could already fetch the results
synchronized (this.cancelLock) {
if (_rs != null) {
while (_rs.next()) {
// construct result IErgebnis
}
} // end if _rs != null
} // ende vom synchronized-Block
if (_erg.getData().size() == 0) {
throw new DataNotFoundException();
}
}
catch (SQLException ex) {
// Logging
if (ex.getErrorCode() == 1013 && this.userCanceled) {
status = "USERBREAK";
throw new QueryCancelledException(ex.getMessage());
} else {
if (ex.getErrorCode() == 1013) {
status = "TIMEOUT";
throw new QueryTimeOutException(ex.getMessage());
} else {
throw ex;
}
}
}
finally {

// synchronization with cancel()
synchronized (this.cancelLock) {
// Resourcen freigeben
if (_rs != null) {
_rs.close();
_rs = null;
}
if (_stmt != null) {
_stmt.close();
_stmt = null;
}
}

if (_conn != null) {
_conn.close();
_conn = null;
}
}
}
// Berichtsdefinition im Ergebnis speichern.
_erg.setDefinition(definition);

//Ergebnis zurückgeben.
return (IErgebnis)_erg;
}
}
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Mar 12 2003
Added on Feb 12 2003
0 comments
931 views