[concurrency-interest] Cancellation convention

Dhanji R. Prasanna dhanji at gmail.com
Wed Jun 7 20:52:14 EDT 2006


Hi, interesting solution. I cant really think of a better one but equally messy:

When the user cancels the request, go into a thread that keeps calling
cancel on the connection until a flag is set by the canceled thread:

//elsewhere in the class
Semaphore s = new Semaphore(1);

//this is the statement being executed
{
s.acquire();
ps.execute();
s.release();
}

//canceling thread
while (s.availablePermits() < 1) {
ps.cancel();
}

Im quite sure a more elegant synchronization solution can be found
with Futures or Locks. In any case I wouldn't be encouraged to use
this method without knowing exactly what the underlying JDBC driver
does on a Statement.cancel().

An unrelated comment: for efficiency and type safety in your
stacktrace analyzer solution you might want to compare:

java.net.SocketStream.class.equals(stackTrace[i])
//etc.

instead of comparing strings.


On 6/8/06, Kazimierz Pogoda <morisil at ncdc.pl> wrote:
> 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
>
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at altair.cs.oswego.edu
> http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
>


More information about the Concurrency-interest mailing list