如何在Oracle下处理大型交易?

4
我们的应用程序基于Hibernate 3.5、Spring 3.1,并在Oracle下运行时遇到了“Max Cursors Exceeded”问题,主要发生在处理大事务(实体数量大,执行的查询数量多)时。但在H2、MS SQL Server或MySQL上运行应用程序时不会出现此类问题。
如果我的调查结果正确,Oracle为事务期间建立的每个ResultSet创建一个游标,这些游标只有在调用Connection(即Hibernate Session)的close方法时才会释放。
我的问题(目前为止):
1. 是否有办法使Oracle在事务进行中清理游标?在特定时间点之后不需要许多查询结果,但是Oracle似乎仍然保持着游标。
2. 是否有“正常”的最大游标设置?默认值为50,我们的大多数客户设置为400-600个游标,但我看过的一些论坛帖子似乎表明几千个更常见。当我们建议增加最大游标计数到5000时,我们的客户DBA似乎都反对。那真的很重要吗?
坦白地说,我读过的大多数论坛帖子都与ResultSet/Statement/Connection泄漏有关,但根据我们的分析,我们并没有这些问题;一旦我们关闭连接,当前游标计数就会恢复正常。我们似乎是唯一一个在单个事务中执行几百个操作时遇到问题的人。这真的很不正常吗?
谢谢任何建议;这让我的头发都掉了。

1
我们经常需要高达8000个。这并不是一个巨大的资源消耗。 - Randy
1
如果设置一个大值有帮助,那就去做吧。只要确保没有泄漏(就像你已经在做的一样)。 - Jayan
1
你有没有尝试过使用更新版本的Hibernate进行实验?3.5版本已经非常老了。你可能在追踪一个早已被修复的很久以前的bug/设计缺陷。例如,我曾经通过Hibernate 3.6做过一些相当棘手的Oracle操作,但从未遇到过这个问题。 - Gimby
我们在下一个小版本中计划升级到Hibernate 4,因此到目前为止还没有考虑升级到3.6...但我现在要试着升级一下。谢谢。 - Gwaptiva
在几乎所有情况下,遇到“Max Cursors Exceeded”问题都表示您的代码存在错误:您没有正确关闭ResultSets和Statements。 - user330315
@a_horse_with_no_name,这样说并不公平,因为有像Hibernate这样的魔法棒工具,它隐藏了所有JDBC细节。 - Gimby
2个回答

3

Oracle会为每个结果集创建游标,并在关闭结果集(jdbc ResultSet.close()或类似方法)时释放它。每个会话默认最多可打开50个游标,这对于任何设计良好的应用程序来说都足够了(我曾经测试过,在生产模式下,它从未超过20个)。

您应该检查如何使Hibernate在获取结果集后关闭结果集。通常,如果一个会话确实需要1000个打开的游标,我无法想象它应该做什么。我从未看到设置max_open_cursors超过1000,所以我猜,对于设计不良的应用程序来说,这也足够了(但是...事实上,完美没有极限,而且我从不使用Hibernate)。

每个游标都意味着一些内存,因此增加max_open_cursors并不是零成本的解决方法。


我曾经在某个地方看到过(别问我在哪里,我希望我还记得,但感觉我已经读了每一个带有Oracle这个词的网上文档),Oracle仅会在调用Connection.close时删除游标。 因此,我又仔细检查了一遍代码并发现了另外一两处可能的泄漏,我们现在正在重新测试。 - Gwaptiva

2
你会发现你存在某种资源泄漏。这种问题在99.99%的情况下是由应用程序中的错误导致的。尽可能使用Java7构造try-with-resources。通常调查此类问题的方法如下:
  • 从DBAs请求SELECT_CATALOG_ROLE(这将使您访问Oracle视图v$
  • 让应用程序运行,同时浪费资源
  • 通过select * from v$open_cursor;检查打开的游标。如果你幸运的话,每个泄漏的游标都会得到Sql查询。
  • 如果您没有使用hibernate,则sql文本将直接指向源代码中的位置。但由于您使用hibernate,所以只能猜测。实体管理器有时非常不可预测。

PS:光标类似于JVM中的线程。它是在“某个”虚拟机中执行某些代码的位置。您可以在单个连接上拥有多个游标。当您关闭结果集时,游标被关闭。通过这样做,您告诉Oracle您不再关心来自SQL查询的任何进一步的行。当然,当您关闭连接时,所有其游标也将关闭。但请不要在仅需要关闭结果集时关闭连接。打开新连接是非常耗费资源的任务。


谢谢,我正在做这件事情(请参考我对Sanders the Softwarer的帖子的评论)。 - Gwaptiva

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接