Hello all,
  I wanted to share a hairy issue we discovered recently and see if people had other solutions, experiences or enhancement ideas. I recently joined a Servlet project using iBatis and Hibernate. When iBatis statements were needed, they would attach the current Connection object to the SqlMapClient object using setUserTransaction and execute insert/update, etc. This worked great.
 
One of the first things I had to do was to test the app in Websphere. In Tomcat everything worked great, but we found that the app would hang in WAS after a while. After much pulling of hair, an IBM support engineer showed us how to dump the JVM state to disk. We found that after WAS hung, all the Servlet threads were in the wait state inside the class common.util.Throttle. Apparently, if you simply call setUserConnection and not openSession, the client *implicitly* creates a SqlMapSession and stores it in a ThreadLocal variable (and hence its thread-safe internally). The problem was that nothing would call the close method on this after it was created! Because of this, each new Thread object would cause a new SqlMapSession to be created and stored. Once we hit the magic number of 129 distinct threads over time, the app would hang. (The default number of active sessions is 128.) As it turns out, WAS continuously creates new threads, whereas Tomcat does so much less often. The Thread creation logic was even more rapid is WAS 6.0.
 
My fix was to instead call openSession(Conn) and then call session.close at the end of the request to "checkin" the SqlMapSession an decrement the Throttle counter for SqlMapSessions. I couldn't figure out how to close the implicit session using the SqlMapClient interface.  Perhaps it would be useful to add a method to SqlMapClient such as "closeImplicitThreadSession" or something like that?
 
Thanks much,
 
Steve

Reply via email to