Skip to content

hibernate druid oracle 下出现ORA-01000: maximum open cursors exceeded错误

在使用hibernate5 与 druid 时候,开发机器都不存在问题,而在测试的时候出现了ORA-01000: maximum open cursors exceeded 的错误.

在查询之后发现,不是因为

ava代码在执行conn.createStatement()和conn.prepareStatement()的时候,实际上都是相当与在数据库中打开了一个cursor。尤其是,如果你的createStatement和prepareStatement是在一个循环里面的话,就会非常容易出现这个问题。因为游标一直在不停的打开,而且没有关闭。

的问题。

仔细分析后 发现是因为系统启动的时候默认开启了hibernate 更新表结构的配置。

我们业务系统的表多大近400张表,hibernate会进行大量的查询与更新.这时候就会出现如上所说的问题.

因为hibernate session的方式,都是通过ThreadLocal来的,并且确认会在数据库操作完成之后,在finally中执行Session.close()。但是 在close的时候,并不会按照jdbc的规范去做,它只是回到连接池,而不是真正关闭。所以执行Session.close后,但是Statement没有被同时关闭,而且因为仍然被应用也不会被gc,长时间运行就会造成游标过大。

hibernate官方已有类似问题。

 

Q:After a while, Oracle throws this exception: too many open cursors

A:The Oracle JDBC driver doesn’t much like to have its prepared statements cached. Disable PreparedStatement caching for the connection pool.

方式一: 也就是关闭连接池的PreparedStatement。
在druid 的情况下,默认是推荐oracle打开,mysql关闭的.

druid poolPreparedStatements 参数解释如下:

是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。

方式二:增大数据库游标大小.  这种方式还在具体测试中,是否能真正的解决问题。

Oracle中默认游标最大值是300,增大操作如下:

sqlplus /nolog

SQL>conn /as sysdba

SQL>show parameter open_cursors;

SQL>alter system set open_cursors=1200 scope=both;

发表评论

电子邮件地址不会被公开。 必填项已用*标注