fer*_*olo 5 java sql-server jtds jdbc glassfish
我有一个在Glassfish上运行的Java EE应用程序,并通过jTDS连接到MSSQL Server 2008.由于某些未知原因,数据库连接在请求期间意外关闭.该应用程序是巨大的,但这里是错误发生的总结:
在Glassfish的设置,与创建一个连接池asadmin create-jdbc-connection-pool和asadmin create-jdbc-resource.数据源类是net.sourceforge.jtds.jdbcx.JtdsDataSource.
当Glassfish上升时,它调用我们的ServletContextListener.contextInitialized()实现,我们从JNDI获取数据源.数据源存储在静态变量中.
有一段时间,一切都很顺利.处理所有请求,不关闭任何连接.我们的应用程序使用Timer和MDB(消息驱动Bean)EJB执行处理.
这是一个示例onMessage()实现:
public void onMessage(Message message) {
this.message = message;
this.connection = dataSource.getConnection(userName, password);
try {
doQuery1();
doTransaction1();
doTransaction2();
doQuery2();
doQuery3();
} finally {
this.connection.close();
this.connection = null;
}
}
Run Code Online (Sandbox Code Playgroud)
最终,我们开始得到以下异常(在一小时内发生约100次):
java.sql.SQLException: Invalid state, the Connection object is closed.
at net.sourceforge.jtds.jdbc.ConnectionJDBC2.checkOpen(ConnectionJDBC2.java)
at net.sourceforge.jtds.jdbc.ConnectionJDBC2.prepareStatement(ConnectionJDBC2.java)
at net.sourceforge.jtds.jdbc.ConnectionJDBC2.prepareStatement(ConnectionJDBC2.java)
at com.sun.gjc.spi.base.ConnectionHolder.prepareStatement(ConnectionHolder.java:475)
at com.acme.myejbs.MyMDB.doQuery2(MyMDB.java:123)
at com.acme.myejbs.MyMDB.onMessage(MyMDB.java:614)
at sun.reflect.GeneratedMethodAccessor115.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java)
at java.lang.reflect.Method.invoke(Method.java)
at com.sun.enterprise.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1011)
...
at $Proxy92.onMessage(Unknown Source)
at com.sun.messaging.jms.ra.OnMessageRunner.run(OnMessageRunner.java)
at com.sun.enterprise.connectors.work.OneWork.doWork(OneWork.java:77)
at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:555)
Run Code Online (Sandbox Code Playgroud)
异常发生在随机JDBC调用中.有时是在ResultSet迭代期间,有时是在查询执行期间.
在极少数情况下(一小时内7次),我们会遇到以下异常:
java.sql.SQLException: Error in allocating a connection. Cause: This Managed Connection is not valid as the phyiscal connection is not usable
at com.sun.gjc.spi.base.DataSource.getConnection(DataSource.java:136)
at com.acme.myejbs.MyMDB.onMessage(MyMDB.java:614)
at sun.reflect.GeneratedMethodAccessor115.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java)
at java.lang.reflect.Method.invoke(Method.java)
at com.sun.enterprise.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1011)
...
at $Proxy92.onMessage(Unknown Source)
at com.sun.messaging.jms.ra.OnMessageRunner.run(OnMessageRunner.java)
at com.sun.enterprise.connectors.work.OneWork.doWork(OneWork.java:77)
at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:555)
Run Code Online (Sandbox Code Playgroud)
同样在非常罕见的情况下(一小时内5次)我们得到这个例外:
java.sql.SQLException: I/O Error: Connection reset by peer: socket write error
at net.sourceforge.jtds.jdbc.TdsCore.executeSQL(TdsCore.java)
at net.sourceforge.jtds.jdbc.JtdsStatement.executeSQLQuery(JtdsStatement.java)
at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.executeQuery(JtdsPreparedStatement.java)
at com.acme.myejbs.MyMDB.doQuery2(MyMDB.java:126)
at com.acme.myejbs.MyMDB.onMessage(MyMDB.java:614)
...
Caused by: java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java)
at java.net.SocketOutputStream.write(SocketOutputStream.java)
at java.io.DataOutputStream.write(DataOutputStream.java)
at net.sourceforge.jtds.jdbc.SharedSocket.sendNetPacket(SharedSocket.java)
at net.sourceforge.jtds.jdbc.RequestStream.putPacket(RequestStream.java)
at net.sourceforge.jtds.jdbc.RequestStream.flush(RequestStream.java)
... 44 more
Run Code Online (Sandbox Code Playgroud)
在极少数情况下,我们会遇到这个可怕的异常(jTDS中的NPE):
java.lang.NullPointerException
at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.executeQuery(JtdsPreparedStatement.java)
at com.acme.myejbs.MyMDB.doQuery2(MyMDB.java:126)
at com.acme.myejbs.MyMDB.onMessage(MyMDB.java:614)
...
Run Code Online (Sandbox Code Playgroud)
我们无法找到为什么会这样.在请求期间,使用的连接永远不会空闲超过一秒.我们不知道是谁放弃了连接.它可能是网络不稳定,但我猜jTDS应该只产生与网络相关的异常,对吧?
另一种选择是Glassfish连接池的一些策略或配置(也许Glassfish过早关闭物理连接),但我们如何跟踪它?
最后,MS SQL Server 2008可以远程删除连接,但是我们如何监视服务器端以了解它是否正在发生?
尝试使用 SQL Server Profiler http://msdn.microsoft.com/en-us/library/ms187929.aspx 您可以从模板“标准”开始,因为它包含事件:审核登录、审核注销、ExistingConnection http://msdn.microsoft.com/en-us/library/ms187929.aspx /msdn.microsoft.com/en-us/library/ms190176.aspx 我认为它们对您来说最重要
| 归档时间: |
|
| 查看次数: |
8343 次 |
| 最近记录: |