2008-11-01
Groovy でもコネクションのクローズを忘れずに。
Groovy ラクチンだなー♪ と思いつつ、サーバー上でGroovyを動かしていたら、以下のエラー。
2008/11/01 18:21:38 org.apache.catalina.core.StandardWrapperValve invoke 致命的: サーブレット HogeServlet のServlet.service()が例外を投げました java.lang.IllegalStateException: com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException: Data source rejected establishment of connection, message from server: "Too many connections" at OfWadsServlet.service(OfWadsServlet.java:35) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447) at java.lang.Thread.run(Thread.java:619) Caused by: com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException: Data source rejected establishment of connection, message from server: "Too many connections" at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:921) at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1070) at com.mysql.jdbc.Connection.createNewIO(Connection.java:2775) at com.mysql.jdbc.Connection.<init>(Connection.java:1555) at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:285) at java.sql.DriverManager.getConnection(DriverManager.java:582) at java.sql.DriverManager.getConnection(DriverManager.java:185) at groovy.sql.Sql.newInstance(Sql.java:136) at groovy.sql.Sql.newInstance(Sql.java:157) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:86) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:230) at groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1105) at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:749) at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:170) at DatabaseResource.init(DatabaseResource.groovy:9) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:86) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:230) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:912) at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodOnCurrentN(ScriptBytecodeAdapter.java:78) at DatabaseResource.<init>(DatabaseResource.groovy:5) at OfWadsServlet.service(OfWadsServlet.java:15) ... 13 more
mysql でコネクション数を見てみる*1と、見事にリーク*2してました。
mysql> show status like 'Threads_connected'; +-------------------+-------+ | Variable_name | Value | +-------------------+-------+ | Threads_connected | 4 | +-------------------+-------+ 1 row in set (0.00 sec)
コネクションの最大数が5で、1回のアクセスで2回groovy.sql.Sql クラスを生成しているので、1回のアクセスあたり2つのコネクションがリークしていたわけです。ということで、リクエスト毎にコネクションのクローズをするとともに、Sql.getConnection() でコネクションを取得して使いまわすように修正しました。
groovy で groovy.sql.Sql クラスを使う場合でも、当然コネクションのクローズ(groovy.sql.Sql#close())はきちんとやらなくちゃですね。
油断してました (^^;
トラックバック - http://d.hatena.ne.jp/beyondseeker/20081101/1225533196
リンク元
- 172 http://www.google.co.jp/search?q=MySQLNonTransientConnectionException&hl=ja&lr=lang_ja&sa=X&oi=lrtip&ct=restrict&cad=9
- 98 http://www.google.co.jp/url?sa=t&rct=j&q=MySQLNonTransientConnectionException%3A+Too+many+connections&source=web&cd=1&ved=0CBsQFjAA&url=http://d.hatena.ne.jp/beyondseeker/20081101/1225533196&ei=bS6ETvLcBvD4mAW4ucgR&usg=AFQjCNHmNb3z7B0Q
- 70 http://www.google.co.jp/search?hl=ja&q=MySQLNonTransientConnectionException&btnG=検索&lr=lang_ja
- 59 http://www.google.co.jp/search?q=Data+source+rejected+establishment+of+connection&btnG=検索&hl=ja&lr=lang_ja&client=firefox-a&channel=s&rls=org.mozilla:ja:official&hs=FkY&sa=2
- 50 http://www.google.co.jp/search?hl=ja&source=hp&q=MysqlNontransientconnectionexception&lr=&aq=f&oq=
- 38 http://search.yahoo.co.jp/search?p=MySQLNonTransientConnectionException&ei=UTF-8&fr=top_ga1&x=wrt
- 36 http://www.google.co.jp/search?sourceid=navclient&hl=ja&ie=UTF-8&rlz=1T4GZAZ_jaJP280JP280&q=MySQLNonTransientConnectionExceptionとは
- 31 http://www.google.co.jp/search?hl=ja&client=firefox-a&rls=org.mozilla:ja:official&hs=V9R&q=servlet+コネクション+クローズ&btnG=検索&lr=lang_ja
- 25 http://search.yahoo.co.jp/search?p=org.apache.catalina.core.StandardWrapperValve+invoke+Servlet.service()が例外を投げました&search.x=1&fr=top_ga1_sa&tid=top_ga1_sa&ei=UTF-8&aq=&oq=
- 23 http://www.google.co.jp/search?q=com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException:&hl=ja&rlz=1T4SUNA_jaJP297JP297&lr=lang_ja&sa=X&oi=lrtip&ct=restrict&cad=8




