简体   繁体   中英

JDBC cancel Oracle stored procedure call

I have a very complex oracle stored procedure that searches and retrieves some data. The procedure returns an output parameter - an oracle cursor. I execute the procedure by JDBC:

CallableStatement stmt = conn.prepareCall("{call myprocedure(?,?,?,?}");

The problem is, the queries can sometimes take quite long (few minutes) and i would like user to be able to cancel the query anytime by clicking button. I have reference to stmt object, but unfortunatelly calling stmt.cancel() (from other thread) has NO EFFECT.

On the other hand when i change the CallableStatement sql to some query like:

CallableStatement stmt = conn.prepareCall("select * from all_objects");

i get "java.sql.SQLTimeoutException: ORA-01013: user requested cancel of current operation" after calling stmt.cancel() - so thats the right reaction.

Does that mean than i cannot cancel stored procedure call via jdbc, but only simple select statements? Does anyone else had and resolved similar problem?

I guess i could cancel the query by oracle kill session, but i use connection pooling (jboss) and i have plenty of sessions for the same user existing.

Database Product Version is Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production JDBC Driver Version is 11.2.0.4.0

any help will be appreciated.

Is that procedure read-only or it writes some data? Try to trace that session on db level and look into the trace file. You can also check v$undostat(used undo blocks) for that particular session. The OCIBreak call does not rollback the session, but might rollback the statement which was interrupted.

Even if you kill the session it will not die immediately. It just has status KILLED and it will rollback everything before it really dies.

If "used undo blocks" in v$undostat is increasing then the session is "doing something". If it is decreasing, the session is rolling back and you have no other option then wait till it is done.

EDITED: In OCI the OCIBreak call is implemented as out-of-band packet. It uses a special field in TCP header. Such a packet can be identified easily by using tcpdump. So even if you do not have necessary privs. on database side you can at least verify, that Break packet was sent to the database.

When you are 100% sure that the break was sent to the database, then you have to investigate on db server side. I think that some DDL statements like "drop user cascade" can not be interrupted.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM