在 finally block 中关闭 JDBC 资源(如数据库连接)之类的资源(如 Spring Framework 所做的 org.springframework.jdbc.support.JdbcUtils.closeConnection(Connection con) )时,我应该捕获所有异常(捕获 Throwable)还是应该只捕获 SQLException 并让任何其他异常从 close() 抛出的未经检查的异常通过在 try 部分中屏蔽异常或在我的代码中的一切正常时抛出异常来混淆原始调用者,而不是像 Spring Framework 那样只记录 JDBC 驱动程序异常?
最佳答案
请注意,Spring 有充分的理由这样做:
- Spring 是一个“非常特殊的应用程序”(与 reasonable application 相对)。它是数千家公司使用的框架,拥有数百种 JDBC 实现,无论它们有什么错误,它都需要经得起考验。
- 他们在评论中具体解释了捕获 Throwable 的原因:
“//我们不信任 JDBC 驱动程序:它可能会抛出 RuntimeException 或 Error。
”。当你做一些需要解释的事情时,你会在代码中添加注释,在这种情况下 - 违反最佳实践。 - 此代码必须处理数百个 JDBC 驱动程序版本,其中许多版本使用 native 代码并可能产生异常错误。
- 我相信,Spring 的异常处理程序是精心手工制作的,不会调用任何内存分配,甚至不会调用一个新的
String
,并满足一些更严格的限制。否则,它将无法在捕获OutOfMemoryError
或VirtualMachineError
时存活下来。
不要捕获 Throwable
。 Error
,其子类,表示:“An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch.”
此外,捕获Exception
通常是不合理的。例如,即使 close()
抛出一个 IndexOutOfBoundsException
,您也想尽可能大声地向您的团队、您的客户和他的 SE 宣布这一切应该知道 JDBC 驱动程序是不可信任的。 关闭()
is only allowed to throw SQLException , 时期。
因为,好吧,数据库是他们的主要 Assets ,我们需要一个可用的驱动程序。
只有作为最后的手段,就像在这个 Spring 示例中一样,当您知道您将使用有故障的驱动程序时,这是可以接受的。
关于java - 在 finally block 上关闭 JDBC 资源时,我应该捕获所有异常还是只捕获 SQLException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34664936/