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

发布于 2024-11-07 09:04:27 字数 440 浏览 1 评论 0原文

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

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

我想这与读取游标时出现某种死锁有关,或者这可能是 jdbc 驱动程序中的错误(我使用的版本:ojdbc6 - 11.1.0.7.0)? 有什么想法吗?

谢谢

I have a web application which executes oracle stored procedures and shows the results on a browser.
The technology stack is as follows: Browser <-> spring mvc <-> [(tomcat)jboss] <-jdbc-> oracle.
The stored procedures have an out cursor for the results and the java code uses that cursor to retrieve the resultset.

Everything was running fine until a new stored procedure was added, which although terminates fast enough in SQL Developer, it freezes when it gets called from the application. The java debugging showed that the code freezes at the OracleCallableStatement.execute. Initially I thought there was something wrong with the procedure but it does run successfully on sql developer, so I am now pointing more towards a jdbc problem...

I guess this has to do with some sort of deadlock while reading the out cursor, or could it be a bug in the jdbc driver (version I am using: ojdbc6 - 11.1.0.7.0)?
Any ideas?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

南巷近海 2024-11-14 09:04:28

确保您的会话没有等待的行锁。以下 SQL*Plus 脚本可以为您提供有关如何执行此操作的提示。或者查看 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

Make sure there's no row lock that your session is waiting on. The following SQL*Plus script could give you hints about how to do that. Or have a look in Oracle Enterprise manager (the Oracle web GUI) under Blocking Sessions.

BTW a deadlock is something different that the database would take care of by killing one of the two sessions...

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
傲娇萝莉攻 2024-11-14 09:04:28

凉爽的。我复制了设置(但没有冻结),所以这仍然是一项正在进行的工作。

我相当确定该问题与 Java 中的 XA 事务有关,因为这是从 Java 和 SQLDeveloper 执行存储过程之间的显着差异。由于调用冻结(无限期地?),您可以重现并快速进入 JMXConsole 并从 jboss.system:type=ServerInfo MBean 中滑动线程转储吗?查看完整的堆栈跟踪可以更好地了解线程正在等待什么。

==== 附录 ====

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

====更新====

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

Cool. I reproduced the setup (but did not get a freeze), so this is still a work in progress.

I am fairly certain that the issue is related to the XA transaction in Java since that is the significant difference between executing the stored proc from Java and from SQLDeveloper. Since the call freezes (indefinitely ?), can you reproduce and scoot into JMXConsole and swipe a thread dump from the jboss.system:type=ServerInfo MBean ? Seeing a full stack trace will give a better idea of what the thread is waiting on.

==== Addendum ====

Are there any pragmas, DDL or any other transaction affecting clauses in the stored procedure or any of it's dependencies ?

==== Update ====

The thread is runnable so we know the client is simply waiting on a response from the server. I thought about the DDL potentially affecting the Transaction, but based on your pseudo-code, the temporary tables are all created implicitly using the WITH statement, which I verified does not trigger a commit. Can you confirm that there are no CREATE TEMPORARY TABLE statements ?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文