Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
198 views
in Technique[技术] by (71.8m points)

java - 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.

I am assuming 'try with resources' closes the resource, that is instantiated - con in this case. Normally you'd close session and connection each individually. 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?

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. Or is my interpretation wrong and just boilerplate code?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Your interpretation is correct, try-with-resources will close only resources explicitly declared in resources block.

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. This mechanism doesn't have anything to do with the garbage collector tho (which would just remove an object without releasing the resource).

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. Consider a following case:

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

In this example, FileInputStream will be created first. Just then it will be passed into a contructor of BufferedInputStream. What would happen when an exception occurs during creation of BufferedInputStream? FileInputStream won't ever be closed. 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. The following is stated in JSL - 14.20.3.1. Basic try-with-resources :

In a basic try-with-resources statement that manages multiple resources:

If the initialization of a resource completes abruptly because of a throw of a value V, then:

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.

There are probably more cases that might cause resource leak as well.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

56.8k users

...