2011-05-16 113 views
3

我有一个web应用程序,它执行oracle存储过程并在浏览器上显示结果。 技术栈如下:浏览器< - > spring mvc < - > [(tomcat)jboss] < -jdbc-> oracle。 存储过程具有结果的外部游标,并且java代码使用该游标来检索结果集。Oracle存储过程在通过jdbc调用时挂起

一切都运行良好,直到添加了一个新的存储过程,尽管在SQL Developer中足够快地终止,但它从应用程序调用时会冻结。 java调试显示代码在OracleCallableStatement.execute处冻结。最初我以为这个过程出了点问题,但是它在sql开发者上运行的很成功,所以我现在更多的指向了一个jdbc问题......

我想这与读取一些死锁有关out cursor,或者它可能是jdbc驱动程序中的错误(我使用的版本是:ojdbc6 - 11.1.0.7.0)? 任何想法?

谢谢

+0

你可以发布存储过程代码和调用JDBC代码吗? – Nicholas 2011-05-17 13:39:02

+0

我可以给你一些代码的提示; – ttr13p 2011-05-26 10:29:49

+0

不幸的是我不能打印代码,但可以描述它。存储过程非常复杂且效率不高。但它确实在sql开发人员中相对较快地终止; PROCEDURE stored_procedure(v_cur OUT SYS_REFCURSOR) IS BEGIN OPEN v_cur为 WITH first_temp_table AS ( SELECT FROM <内部联接但也有许多笛卡尔积> WHERE ) second_temp_table AS ( SELECT FROM <内连接,但也有很多笛卡尔产品> WHERE <使用first_temp_table>的子查询> )<在临时表上进行最终查询选择,具有非常复杂的不合理选择和连接> – ttr13p 2011-05-26 10:53:39

回答

2

请确保您的会话没有等待的行锁。以下SQL * Plus脚本可以为您提供有关如何执行此操作的提示。或者在Blocking Sessions下查看Oracle Enterprise Manager(Oracle Web GUI)。

BTW死锁是不同的东西,数据库会照顾杀死两会的一个...

REM Purpose 
REM ------- 
REM Display locks currently held and requested. Displays which session a 
REM blocked lock is waiting for. 
REM 
REM Ver Who When  What 
REM --- --- ----  ---- 
REM 1.0 DrB 12-Dec-97 Initial version 
col uname  head "Username" form a12 
col sid  head "SID"  form 999 
col ltype  head "Type"  form a4 
col lmode  head "Mode"  form a10 
col blocked head "Wait"  form a4 
col details head "Details" form a40 
set verify off 
set pause on 
accept user prompt "Username [%]: " 
select SubStr('alter system kill session ''' || s.sid || ',' || s.serial# || ''';', 1, 40) as kill, s.username uname, 'DML' ltype, 
    decode (l.lmode,1,'Null', 
        2,'Row-S', 
        3,'Row-X', 
        4,'Share', 
        5,'S/Row-X', 
        6,'Exclusive') lmode, 
    decode (l.request,0,'No','Yes') blocked, 
    u.username||'.'||o.name details, 
    Nvl(s.Program, s.Module) What 
from v$session s, v$lock l, sys.obj$ o, all_users u 
where s.username like nvl(upper('&user'||'%'),'%') 
and s.sid = l.sid 
and l.id1 = o.obj# 
--and l.type = 'TM' 
and o.owner# = u.user_id(+) 
union all 
select SubStr('alter system kill session ''' || s.sid || ',' || s.serial# || ''';', 1, 40) as kill, s.username uname, 
    decode (l.type,'TX','TX', 
       'UL','USR', 
         'SYS') ltype, 
    decode (l.lmode,1,'Null', 
        2,'Row-S', 
        3,'Row-X', 
        4,'Share', 
        5,'S/Row-X', 
        6,'Exclusive') lmode, 
    decode (l.request,0,'No','Yes') blocked, 
    decode (l.request,0,null,'Waiting on session '||to_char(b.sid)) details, 
    Nvl(s.Program, s.Module) What 
from v$session s, v$lock l, v$lock b 
where s.username like nvl(upper('&user'||'%'),'%') 
and s.sid = l.sid 
and l.type != 'TM' 
and l.id1 = b.id1(+) 
and b.request(+) = 0 
order by 5 desc,3 desc,2,1; 
set verify on 
REM End of file 
+0

谢谢你的回答。在电话挂断时看着oracle web gui,我看到有两个相同的查询互相阻塞。我还应该提到,只有当jboss在Unix下运行时才会发生这种情况,而在Windows上运行正常。我尝试使用最新的驱动程序11.2.0.2.0,但没有改变。 – ttr13p 2011-05-17 09:12:43

+0

另外我正在使用oracle.jdbc.xa.client.OracleXADataSource – ttr13p 2011-05-17 09:35:27

0

酷。我转载了这个设置(但没有被冻结),所以这仍然是一个正在进行的工作。

我相当确定该问题与Java中的XA事务有关,因为这是执行Java存储过程和SQLDeveloper之间的显着区别。由于通话冻结(无限期?),您是否可以重新生成JMXConsole,并从jboss.system中滑出一个线程转储:type = ServerInfo MBean?查看完整的堆栈跟踪将更好地了解线程正在等待什么。

==== ====编

是否有任何编译指示,DDL或影响该存储过程或任何其依赖条款的任何其他交易?

==== ====更新

线程可运行,所以我们知道客户只是在等待来自服务器的响应。我想到DDL可能会影响事务,但是根据您的伪代码,临时表都是使用WITH语句隐式创建的,我通过验证不会触发提交。你能否确认没有CREATE TEMPORARY TABLE陈述?

+0

谢谢尼古拉斯。这里是线程转储的特定线程堆栈跟踪: – ttr13p 2011-05-27 09:52:36

+0

线程:....优先级:5,demon:true,threadId:121,threadState:RUNNABLE java.net.SocketInputStream.socketRead0(本地方法) java.net。 SocketInputStream.read(SocketInputStream.java:129) oracle.net.ns.Packet.receive(Packet.java:240) oracle.net.ns.DataPacket.receive(DataPacket.java:92) oracle.net.ns .NetInputStream.getNextPacket(NetInputStream.java:172) oracle.net.ns.NetInputStream.read(NetInputStream.java:117) oracle.net.ns.NetInputStream.read(NetInputStream.java:92) oracle.net。 (NetInputStream.java:77)oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.java:1034) – ttr13p 2011-05-27 09:54:52

+0

oracle.jdbc.driver.T4CMARE ngine.unmarshalSB1(T4CMAREngine.java:1010) oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:588) oracle.jdbc.driver.T4CCallableStatement.doOall8(T4CCallableStatement.java:191) oracle.jdbc.driver .T4CCallableStatement.executeForRows(T4CCallableStatement.java:950) oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1222) oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3387) oracle.jdbc。 driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:3488) – ttr13p 2011-05-27 09:56:03