java—使用连接池和单个连接尝试资源

cczfrluj  于 2021-06-27  发布在  Java
关注(0)|答案(1)|浏览(341)

在代码审阅期间,我发现以下代码段:

try (
   Connection con = new SqlSessionFactoryBuilder()
    .build(configuration)
    .buildFactory()
    .openSession()
    .getConnection()
){
   // do stuff here with 'con' and not close anything   
}

session、connection、sqlsessionfactory都是ibatis实现,但问题在于可关闭接口的任何“堆叠”实现。
我假设“try with resources”关闭资源,在本例中是示例化的-con。通常,您会分别关闭会话和连接。如果使用上述代码,close()方法将只在con对象上调用,那么session不会显式调用,而是依赖于垃圾回收?
使用以下方法代码会更好:

try (
   Session session = new SqlSessionFactoryBuilder()
    .build(configuration)
    .buildFactory()
    .openSession(); 
   Connection con = session.getConnection();
){
   // do stuff here with 'con' and not close anything
}

在我看来,后一种方法似乎更干净,因为它应该正确地调用close()。或者我的解释是错误的,只是样板代码?

mkshixfv

mkshixfv1#

您的解释是正确的,try with resources将仅关闭resources块中显式声明的资源。
然而,在大多数情况下,第一种方法也会起作用。那是因为通常 Closeable 使用另一个 Closeable ,它将尝试在其内部关闭它 close() 方法。这个机制与垃圾收集器tho没有任何关系(它只是删除一个对象而不释放资源)。
除了 Closeable 如果不关闭它的资源,那么在第一种方法中也可能有其他的资源泄漏源。考虑以下情况:

try(BufferedInputStream bufferedInput = new BufferedInputStream(
                                            new FileInputStream("file.txt"))
)

在这个例子中, FileInputStream 将首先创建。就在那时,它将成为一个 BufferedInputStream . 在创建过程中发生异常时会发生什么 BufferedInputStream ? FileInputStream 永远不会关门。另一方面,当您将它们声明为两个独立的资源时,如下所示:

try(FileInputStream input = new FileInputStream("file.txt");
    BufferedInputStream bufferedInput = new BufferedInputStream(input)
)

java本身将确保关闭这两个资源。jsl-14.20.3.1中说明了以下内容。基本资源试用:
在管理多个资源的基本try with resources语句中:
如果资源的初始化由于抛出值v而突然完成,则:
如果所有成功初始化的资源(可能为零)的自动关闭正常完成,那么try with resources语句会因为抛出值v而突然完成。
可能还有更多的情况可能导致资源泄漏。

相关问题