通过jdbc调用时,Oracle存储过程挂起

时间:2011-05-16 14:44:24

标签: oracle stored-procedures jdbc jboss cursor

我有一个Web应用程序,它执行oracle存储过程并在浏览器上显示结果。 技术堆栈如下:浏览器< - > spring mvc< - > [(tomcat)jboss]< -jdbc->神谕。 存储过程有一个结果的out游标,java代码使用该游标来检索结果集。

一直运行正常,直到添加了一个新的存储过程,尽管SQL Developer中的终止速度足够快,但它从应用程序调用时会冻结。 java调试显示代码在OracleCallableStatement.execute处冻结。最初我认为这个程序有问题,但它确实在sql开发人员上成功运行,所以我现在更多地指向一个jdbc问题......

我猜这与读取光标时的某种死锁有关,或者它可能是jdbc驱动程序中的错误(我正在使用的版本:ojdbc6 - 11.1.0.7.0)? 有任何想法吗?

由于

2 个答案:

答案 0 :(得分:2)

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

顺便说一下,死锁是一个不同的东西,数据库可以通过杀死两个会话之一来处理......

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

答案 1 :(得分:0)

冷却。我重新设置了设置(但没有冻结),所以这仍然是一项正在进行的工作。

我很确定这个问题与Java中的XA事务有关,因为这是从Java执行存储过程和从SQLDeveloper执行存储过程之间的重要区别。由于调用冻结(无限期?),您是否可以重现并进入JMXConsole并从 jboss.system:type = ServerInfo MBean中滑动线程转储?查看完整的堆栈跟踪将更好地了解线程正在等待的内容。

====附录====

是否存在任何编译指示,DDL或任何其他影响存储过程中的子句或其任何依赖项的事务?

====更新====

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