[concurrency-interest] Cancellation convention

Kazimierz Pogoda morisil at ncdc.pl
Wed Jun 7 11:48:37 EDT 2006


On Tue, 2006-06-06 at 19:24 +0100, Mike Quilleash wrote:

> Specifically I'm interested in being able to cancel long running JDBC
> calls (using PreparedStatement.cancel()).  Would a sensible way be to
> fork off the PreparedStatement execution in another thread and have
> the main thread wait for the second thread to complete, but if it is
> interrupted then call the PreparedStatement.cancel() and throw an
> exception out to indicate the cancellation succeeded?  Just after some
> best practice advice.

Cancellation of PreparedStatement (CallableStatement in fact) that was
executed by another thread works for me, but there is one issue. It
looks like oracle jdbc driver implementations react to cancel() method
on PreparedStatement only in case when it is hanging on the network
socket. So if we call cancel() on statement before executing thread is
"deep enough" in the execution, cancellation simply doesn't work. To
workaround this i wrote the code that analyzes stack trace of the
statement executor thread:

    private boolean isAwaitingEvent() {
        final StackTraceElement[] stackTrace = getStatementExecutorThread().getStackTrace();
        if (stackTrace.length < 2) {   //it is probably impossible, but maybe is thread is just started, so let's check
            return false;
        }
        final String recentClass = stackTrace[0].getClassName();
        final String recentMethod = stackTrace[0].getMethodName();

        if (!"java.net.SocketInputStream".equals(recentClass) && "socketRead0".equals(recentMethod)) {   //make sure we are hanging on socket
            return false;
        }

        boolean foundCallable = false;
        final String thisClass = getClass().getName();
        for (int i = 1; i < stackTrace.length; i++) {
            final String className = stackTrace[i].getClassName();
            final String methodName = stackTrace[i].getMethodName();
            if ((!foundCallable) && "oracle.jdbc.driver.OracleCallableStatement".equals(className) && "execute".equals(methodName)) {
                foundCallable = true;
                continue;
            } else if (thisClass.equals(className) && "awaitEvent".equals(methodName)) {
                return true;
            }
        }
        return false;
    }


And I'm waiting for this method to return true before I call cancel() on
the statement. Has anyone idea for better workaround?

-- 
"the spirit can only withdraw into a corner. And yet, it is not at all 
 worn out or superfluous, but, like an (eternal) witness, floats above 
 the rubble of culture - almost like an  avenger of God.  As though it 
 awaited a new incarnation."
                                        -- Ludwig Wittgenstein --
Kazimierz Pogoda
mailto:morisil at ncdc.pl



More information about the Concurrency-interest mailing list