一个JFinal4.4在Oracle数据库下使用的BUG

JFinal4.4,在Oracle下使用的时候程序运行一段时间后会遇到错误:“ORA-01000: 超出打开游标的最大数”,查看代码发现在com.jfinal.plugin.activerecord.DbPro类的save方法中,打开了PreparedStatement,在遇到保存错误的情况下,preparedStatement不会被正常关闭,导致会话游标一直被持有,希望在后续版本中能修复。save方法代码如下:

(Config configConnection connString tableNameString primaryKeyRecord record) SQLException {
   String[] pKeys = primaryKey.split()List<Object> paras = ArrayList<Object>()StringBuilder sql = StringBuilder()config..forDbSave(tableNamepKeysrecordsqlparas)PreparedStatement pst(config..isOracle()) {
      pst = conn.prepareStatement(sql.toString()pKeys)} {
      pst = conn.prepareStatement(sql.toString()Statement.)}
   config..fillStatement(pstparas)result = pst.executeUpdate()config..getRecordGeneratedKey(pstrecordpKeys)DbKit.(pst)result >= }


评论区

JFinal

2020-04-09 12:42

这类调用了 DbKit.close(preparedStatement) 的方法都抛出了 SQLException,而在外层会被 try catch 到它,并且会被调用 DbKit.close(connection)

而 DbKit.close(connection) 是会将从 connection 中打开的 preparedStatement 一并关掉,理论上来说是没有问题的

当然,不排除有些数据库驱动或者数据源连接池没有保障 connection.close() 后自动关闭 preparedStatement

所以,jfinal 4.9 已经使用 JDK 7 加入的 try-with-resources 语法对这个地方加强了:
https://gitee.com/jfinal/jfinal/commit/ea4eeefbc4e611e6f794fa77144528480778282e

jfinal 先前的处理方式用了很多年了,是没有问题的

daisy1024

2020-04-16 13:51

@JFinal 我在实际项目中使用的jfinal4.4,数据库是oracle11,由于测试项目脏数据较多,出现了较多的主键冲突,导致项目运行一段时间之后,其他地方的find操作提示ORA0100游标过多,最终定位到preparedStatement在sql异常情况下不会调用DbKit.close的问题。
我这里遇到的问题和这个反馈遇到的实际上是一样的,http://www.jfinal.com/feedback/1728,在oracle中关闭connection还是没能成功释放游标。4.9版本的代码暂时还没更新来看不好确定。

JFinal

2020-04-16 16:12

@daisy1024 使用 mvn clean install 将 4.9 安装到本地用起来

热门反馈

扫码入社