tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alan Chaney <a...@compulsivecreative.com>
Subject Re: Random Connection Closed Exceptions - Question to the code example
Date Mon, 19 Jan 2009 23:24:43 GMT
Hi Stefan

I went and read the comments more carefully and it seems to me that the 
proposed solution is an attempt to avoid a race condition between 
issuing the 'close' in
one thread and then it being  closed again whilst its being used in 
another thread.

If the problem is closing it twice then I can't see why its not just 
closed in the 'finally' block, once for each thread.

If it is a concurrency problem then I suspect that the proposed solution 
in the docs isn't the right one anyway. I'd suspect that the problem is 
more to do with threads not seeing each others memory state properly. 
Isn't this is a case of a variable (in this case 'conn') actually being 
a reference to an object which is shared between threads?
Because of the JVM memory model it is possible for two threads not to be 
properly synchronized - see Doug Lea et.al and 'happens before' . 
Personally, I feel that the correct solution is to synchronize  access 
to the connection object when it is retrieved and closed.

I have to go out now and I don't have any more time to consider this 
today, but I'd be interested to hear other people's comments on this topic.

Regards

Alan Chaney


Stefan Riegel wrote:
> Thanks Alan, just to make the thing really clear. You propose code 
> like this:
>
>     public void execute() {
>         Connection conn = null;
>         Statement stmt = null;
>         ResultSet rs = null;
>         Context envContext = null;
>         try {
>             Context initContext = new InitialContext();
>             envContext = (Context) initContext.lookup("java:/comp/env");
>             DataSource ds = (DataSource) envContext.lookup("jdbc/swex");
>             conn = ds.getConnection();
>             stmt = conn.createStatement();
>             rs = stmt.executeQuery("some sql");
>             // iterate through the result set ...
>         } catch (SQLException e) {
>             e.printStackTrace();
>         } catch (NamingException e) {
>             e.printStackTrace();
>         } finally {
>             if (rs != null) {
>                 try {
>                     rs.close();
>                 } catch (SQLException e) {
>                     e.printStackTrace();
>                 }
>             }
>             if (stmt != null) {
>                 try {
>                     stmt.close();
>                 } catch (SQLException e) {
>                     e.printStackTrace();
>                 }
>             }
>             if (conn != null) {
>                 try {
>                     conn.close();
>                 } catch (SQLException e) {
>                     e.printStackTrace();
>                 }
>             }
>             if (envContext != null) {
>                 try {
>                     envContext.close();
>                 } catch (NamingException e) {
>                     e.printStackTrace();
>                 }
>             }
>         }
>
>
> For me this looks fine but I'm still confused, why they complicated 
> things in the example of "properly written code" 
> http://tomcat.apache.org/tomcat-6.0-doc/jndi-datasource-examples-howto.html? 
>
>
Hmm... frankly the code in the docs you refer to above seems odd to 
me... why repeat in the 'finally' something you've done in the 'try'?

I can see that setting the variables to null would ensure that all 
references were released and the objects were made candidates for garbage
collection but that could be done in the finally block anyway at some 
convenient point.

Obviously in your code you might not want to obtain and release the 
context for every JDBC operation - that would probably be done in some 
kind of start-up/shutdown code for your app, and of course your 
exception handling may need some more work depending upon the way you 
want to present the error
to your users, but I assumed that the issue you are concerned with is 
preventing resource leaks.

Any comments anyone else?

Regards

Alan



> Do I miss some important point here?
>
> Stefan
>
>
> Alan Chaney schrieb:
>> Hi Stefan
>>
>> You don't need to repeat the stmt.close();conn.close() etc in the 
>> 'try' body. The 'finally' by definition is ALWAYS called and that is 
>> where you should do the tidy up...
>>
>> Alan Chaney
>>
>>
>>
>> Stefan Riegel wrote:
>>> I guess I understood the point with the "Random Connection Closed 
>>> Exceptions" Problem.
>>>
>>> See at the end of 
>>> http://tomcat.apache.org/tomcat-6.0-doc/jndi-datasource-examples-howto.html 
>>>
>>>
>>> As I understand, only the connection itself must be protected this 
>>> way. The statement and ResultSet must not. Is the following, 
>>> simplified code also correct?
>>>
>>>   Connection conn = null;
>>>   Statement stmt = null;
>>>   ResultSet rs = null;
>>>   try {
>>>     conn = ... get connection from connection pool ...
>>>     stmt = conn.createStatement("select ...");
>>>     rs = stmt.executeQuery();
>>>     ... iterate through the result set ...
>>
>> // SUPERFLUsOUS
>>>     rs.close();
>>>     stmt.close();
>>>     conn.close(); // Return to connection pool
>>>     conn = null;  // Make sure we don't close it twice
>> //SUPERFLUOUS
>>
>>
>>>   } catch (SQLException e) {
>>>     ... deal with errors ...
>>>   } finally {
>>>           try {
>>>         rs.close();
>>>       } catch (SQLException e) {
>>>         // deal with errors
>>>       }
>>>           try {
>>>         stmt.close();
>>>       } catch (SQLException e) {
>>>         // deal with errors
>>>       }
>>>         if (conn != null) {
>>>               try {
>>>             conn.close();
>>>         } catch (SQLException e) {
>>>             // deal with errors
>>>         }
>>>               conn = null;
>>>         }
>>>   }
>>>
>>> Thanks.
>>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
>> For additional commands, e-mail: users-help@tomcat.apache.org
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Mime
View raw message