【问题标题】:In what cases can a statement.close throw exception? What does it mean for the connection?在什么情况下 statement.close 会抛出异常?这对连接意味着什么?
【发布时间】:2018-08-01 14:54:15
【问题描述】:

我们到处都看到 Statement.close() 通过吃掉它抛出的异常来“处理”。什么情况下它可以首先抛出异常?对于创建此语句的连接意味着什么?

换句话说,statement.close() 什么时候抛出异常,连接是否仍然“健康”可以用于创建新语句?

另外,如果 resultset.close() 抛出,会发生什么?

【问题讨论】:

  • 这取决于您使用的驱动程序。除非驱动程序记录了close() 抛出异常时要采取的措施,否则我会将其记录为调试并尝试得出自己的结论或忽略它。
  • "无处不在我们看到 Statement.close() 是通过吃掉异常来“处理”的” 非凡的主张需要非凡的证据。我只吞下/忽略玩具应用程序中的异常,或者如果我确定忽略它是安全的,否则至少我会记录它,或将其包装在应用程序特定的异常中(通常是运行时,有时检查)。

标签: java database jdbc database-connection


【解决方案1】:

首先,考虑close() 方法可能需要做什么,以及什么可能导致异常。

例如PreparedStatement可能创建了一个存储过程,需要通过close()方法删除。 executeQuery() 可能打开了一个游标,供ResultSet 使用,close() 需要关闭该游标。

异常当然可能是内部错误,但很可能是通信错误,导致关闭操作无法成功。

那么,这是什么意思?这意味着资源没有被明确清理。由于您的操作已经完成,通常可以忽略那些close() 异常,因为无论如何资源最终都会被回收。

但是,由于原因可能是通信错误,因此连接很可能已断开,这意味着无论您接下来尝试什么,都会遇到另一个异常,从而更不可能处理 close() 异常很重要。

为了安全,异常意味着有问题,除非你检查异常以了解它有多糟糕,否则你应该中止你正在做的任何事情。如果您想重试,应该建立一个新的连接。

但是,如前所述,忽略close() 异常并不是一个大问题。这可能会导致资源泄漏,但如果问题很严重,那么无论如何您都会在下一个操作中遇到另一个异常。

【讨论】:

  • 忽略它并不完全安全,例如在自动提交模式下,语句关闭会触发事务完成,这可能导致提交失败。这意味着您刚刚忽略了一个可能意味着您丢失数据的事件。
  • @MarkRotteveel 是的。我没有考虑到这一点,因为我从来没有在自动提交模式下运行过。
【解决方案2】:

这种异常的最简单情况:处理该语句的连接在您尝试关闭该语句之前或如果该语句已关闭 - 不知何故 - 已经关闭。对于 jdbc,连接应该是健康的。 一般来说:正如彼得所说,如果驱动程序的文档不包含如何处理此类异常的任何建议,您只能记录或调试它。也许你可以重新建立连接以确保它是健康的。

【讨论】:

  • 在关闭的语句上调用 close() 不应引发异常。 JDBC 规范指定(自 JDBC 4 IIRC 起),已关闭对象上的 close() 是无操作的。而且由于关闭连接会关闭其语句,因此关闭已关闭连接上的语句也不应该导致异常。
【解决方案3】:

当您关闭语句时,可能会发生很多事情。关闭语句时可能会发生以下基本情况:

  • 打开的结果集(如果有)已关闭,这可能需要与数据库进行通信
  • 数据库服务器上的语句句柄释放,需要与数据库通信

鉴于这涉及到与数据库的通信,可能会发生各种错误:文件系统错误、网络连接问题等。这些可以忽略不计,但也可能表明您的应用程序或数据库存在严重问题。

语句关闭的次要影响可以是事务完成(提交或回滚)。例如,当您执行生成结果集的数据修改语句时,这可能在自动提交模式下发生:当结果集在语句结束时关闭时,事务结束。如果此事务提交失败,而您忽略它,则您的应用程序可能刚刚发生数据丢失事件(因为数据未持久化),而您只是继续忽略它。

换句话说:你不应该只是忽略或吞下来自Statement.close() 的异常,除非你绝对确定不会产生有害影响。至少记录它们,以便您可以在日志中跟踪它们(并且可能定义有关记录的异常数量的警报),但始终考虑是否需要将它们包装在特定于应用程序的异常中并将它们放在调用链的更高层进行处理,或 - 对于提交失败 - 如果您需要重试任何操作。

【讨论】:

    猜你喜欢
    • 2010-12-29
    • 1970-01-01
    • 2011-02-16
    • 1970-01-01
    • 2021-09-30
    • 1970-01-01
    • 2023-01-03
    • 2012-04-23
    • 2013-01-17
    相关资源
    最近更新 更多