简体   繁体   English

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

[英]Try with resources using a connection pool and single connection

During a code review I found the following code snippet:在代码审查期间,我发现了以下代码片段:

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

Session, Connection, SqlSessionFactory are iBatis implementations, but the questions is interested in any 'stacked' implementation of the Closable interface. Session、Connection、SqlSessionFactory 是 iBatis 实现,但问题对 Closable 接口的任何“堆叠”实现感兴趣。

I am assuming 'try with resources' closes the resource, that is instantiated - con in this case.我假设“尝试使用资源”关闭资源,即实例化 - 在这种情况下是con Normally you'd close session and connection each individually.通常你会关闭 session 并单独连接每个。 If using the above code the close() method will just be called on con object, so session is not explicitly called and will rely on the garbage collection?如果使用上面的代码, close()方法只会在con object 上被调用,所以 session 没有被显式调用并且会依赖垃圾回收?

Will the code be any better using:使用以下代码是否会更好:

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

The latter approach seems cleaner in my eyes as it should call close() correctly.后一种方法在我看来似乎更干净,因为它应该正确调用close() Or is my interpretation wrong and just boilerplate code?或者我的解释是错误的,只是样板代码?

Your interpretation is correct, try-with-resources will close only resources explicitly declared in resources block.您的解释是正确的,try-with-resources 只会关闭在资源块中明确声明的资源。

However, in most cases the first approach will work as well.但是,在大多数情况下,第一种方法也可以。 That is because usually when some Closeable uses another Closeable , it will try to close it inside of its close() method.这是因为通常当某些Closeable使用另一个Closeable时,它会尝试在其close()方法内关闭它。 This mechanism doesn't have anything to do with the garbage collector tho (which would just remove an object without releasing the resource).这种机制与垃圾收集器没有任何关系(它只会删除 object 而不会释放资源)。

Other than the situation where a Closeable wouldn't close its resources, there could be other sources of resources leak in the first approach as well.除了Closeable不会关闭其资源的情况外,在第一种方法中也可能存在其他资源泄漏源。 Consider a following case:考虑以下情况:

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

In this example, FileInputStream will be created first.在此示例中,将首先创建FileInputStream Just then it will be passed into a contructor of BufferedInputStream .就在那时它将被传递给BufferedInputStream的构造函数。 What would happen when an exception occurs during creation of BufferedInputStream ?在创建BufferedInputStream过程中发生异常时会发生什么? FileInputStream won't ever be closed. FileInputStream永远不会关闭。 On the other hand, when you declare those as two separate resources like so:另一方面,当您将它们声明为两个单独的资源时,如下所示:

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

Java itself will make sure that both of the resources will be closed. Java 本身将确保关闭这两个资源。 The following is stated in JSL - 14.20.3.1.以下内容在JSL - 14.20.3.1 中进行了说明。 Basic try-with-resources : 基本的资源尝试

In a basic try-with-resources statement that manages multiple resources:在管理多个资源的基本 try-with-resources 语句中:

If the initialization of a resource completes abruptly because of a throw of a value V, then:如果资源的初始化由于抛出值 V 而突然完成,则:

If the automatic closings of all successfully initialized resources (possibly zero) complete normally, then the try-with-resources statement completes abruptly because of a throw of the value V.如果所有成功初始化的资源(可能为零)的自动关闭正常完成,则 try-with-resources 语句会因为抛出值 V 而突然完成。

There are probably more cases that might cause resource leak as well.可能还有更多可能导致资源泄漏的情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM