最近做了个项目。。测了好几遍了。。。然后突然测试那边的数据库环境执行一条SQL语句不行了。报错“ java.net.SocketException: Connection reset”
SQL语句为(
select ID as id,collageID as collageId,parentID as parentId ,orgName as orgName)其中F_GetChildren是一个函数,传个父节点的ID值返回所有全递归子节点。这sql语句绝对没问题,在本地和测试的查询分析器里执行是正常的。然后在本机测试了程序下可以。其他开发部门同事机子上也可以。就测试部门不可以。我把本地库分离下来附加到测试那边的环境。还是不行。我的猜测就是测试那边数据库环境出现错误了。。。但是却不知道是哪出错了。。。正要放弃时突然发现我如果不用PreparedStatement的预编译
from collage_orgGroups where ID IN(SELECT ID FROM dbo.F_GetChildren(?))
pst.setInt(1,1);直接拼接sql语句
select ID as id,collageID as collageId,parentID as parentId ,orgName as orgName from collage_orgGroups where ID IN(SELECT ID FROM dbo.F_GetChildren(1))就可以。。。。很奇怪。。网上找了很多资料。但是没个准确的解释。希望大家知道了。。说声。。。。
public static void main(String[] args) throws IOException {
Connection conn=null;
PreparedStatement pst=null;
ResultSet rs=null;
try {
conn=getConnByParam("192.168.0.102", "sa", "123", "NewsDBTest");
System.out.println(conn);
String sql="select ID as id,collageID as collageId,parentID as parentId ,orgName as orgName"
+" from collage_orgGroups where ID IN(SELECT ID FROM dbo.F_GetChildren(?))";
pst=conn.prepareStatement(sql);
pst.setInt(1,1);
rs=pst.executeQuery();
while(rs.next()){
System.out.println(rs.getString("id")+"---"+rs.getString("orgName")+"---"+rs.getString("parentId"));
}} catch (Exception e) { e.printStackTrace(); }finally{ try { if(conn!=null){ conn.close(); } if(pst!=null){ pst.close(); } if(rs!=null){ rs.close(); } } catch (Exception e) { } } }</pre><br /><br />异常:<pre name="code" class="java">java.sql.SQLException: I/O Error: Connection reset by peer: socket write error at net.sourceforge.jtds.jdbc.TdsCore.executeSQL(TdsCore.java:1053) at net.sourceforge.jtds.jdbc.JtdsStatement.executeSQLQuery(JtdsStatement.java:465) at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.executeQuery(JtdsPreparedStatement.java:776) at cn.com.shanli.collageNews.business.utils.CommUtils.main(CommUtils.java:164)
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:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
at java.io.DataOutputStream.write(DataOutputStream.java:90)
at net.sourceforge.jtds.jdbc.SharedSocket.sendNetPacket(SharedSocket.java:676)
at net.sourceforge.jtds.jdbc.RequestStream.putPacket(RequestStream.java:560)
at net.sourceforge.jtds.jdbc.RequestStream.flush(RequestStream.java:508)
at net.sourceforge.jtds.jdbc.TdsCore.executeSQL(TdsCore.java:1040)
... 3 more
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[F_GetChildren]') AND xtype in (N'FN', N'IF', N'TF'))
BEGIN
execute dbo.sp_executesql @statement = N'Create Function [dbo].F_GetChildren
Returns @Tree Table (ID Int)
As
Begin
Insert @Tree Select ID From collage_orgGroups Where parentID = @Pid
While @@Rowcount > 0
Insert @Tree Select A.ID From collage_orgGroups A Inner Join @Tree B On A.ParentID = B.ID And A.ID Not In (Select ID From @Tree)
Return
End
'
END
①:服务器的并发连接数超过了其承载量,服务器会将其中一些连接Down掉;
Oracle的并发数是否有关?去调一下数据库参数吧
连接未关闭。
建议使用组件
[quote]Connection reset by peer的原因:
经常出现的Connection reset by peer: 原因可能是多方面的,不过更常见的原因是:
①:服务器的并发连接数超过了其承载量,服务器会将其中一些连接Down掉;
②:客户关掉了浏览器,而服务器还在给客户端发送数据;
③:浏览器端按了Stop [/quote]
[code="java"] try {
if(conn!=null){
conn.close();
}
if(pst!=null){
pst.close();
}
if(rs!=null){
rs.close();
}
[/code]
把这个反过来关 试试。
为什么不用框架作这东西
手写jdbc好多好多年没见过了。
首先,使用用框架(自己写的或者像springframework等已有的),这样对错误处理,等等但又有好处,而且一致处理,不会有遗漏,……,好处就不一一列举了。
其次,检查下你的jdbc驱动程序,看看使用的版本是什么,大不了跟踪进去看看,这个是比较诡异的。
其次,尽量不要写:
String sql="select ID as id,collageID as collageId,parentID as parentId ,orgName as orgName"
+" from collage_orgGroups where ID IN(SELECT ID FROM dbo.F_GetChildren(?))";
用一个stringbuilder到string的转换,既是可读性高,又性能好,总而言之,还是少些sql的比较好,特别是使用plsql函数。如果只是测试,那还可以。
再看看你的网络设置吧,具体没有跟踪,只能提供一点参考意见。
另外,再看看你使用的connection关闭是不是硬关闭,如果一个环境是,一个不是,也可能出现。
或者是不是打开的链接受到限制了,在你的机器上。
貌似是关闭连接的时候有问题
[quote="redhat"]首先,使用用框架(自己写的或者像springframework等已有的),这样对错误处理,等等但又有好处,而且一致处理,不会有遗漏,……,好处就不一一列举了。
其次,检查下你的jdbc驱动程序,看看使用的版本是什么,大不了跟踪进去看看,这个是比较诡异的。
其次,尽量不要写:
String sql="select ID as id,collageID as collageId,parentID as parentId ,orgName as orgName"
+" from collage_orgGroups where ID IN(SELECT ID FROM dbo.F_GetChildren(?))";
用一个stringbuilder到string的转换,既是可读性高,又性能好,总而言之,还是少些sql的比较好,特别是使用plsql函数。如果只是测试,那还可以。
再看看你的网络设置吧,具体没有跟踪,只能提供一点参考意见。[/quote]
呵呵,没下文了啊。
[b]对于这个sql语句使用"+"拼接的可读性更好(实际上还是stringbuilder)[/b]
不象是 连接已经满了的问题。
不过确实诡异,跟踪调试下吧!
文中提到:
at cn.com.shanli.collageNews.business.utils.CommUtils.main(CommUtils.java:164)
怎么没给出CommUtils.java:164的代码。
at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.executeQuery(JtdsPreparedStatement.java:776)
猜测是此句:rs=pst.executeQuery(); 产生的异常,如果是的,那么也不是链接突然断开的问题。
如果是rs=pst.executeQuery(); 产生的异常,那还没有到链接关闭的执行。虽然链接关闭顺序确实搞反了。
[quote="jyjava"]貌似是关闭连接的时候有问题[/quote]
bug的可能性?
尝试:
pst.execute();
rs = pst.getResultSet();
什么啊 是那个问号的问题,那个问号貌似不能写到函数参数上。。。。。
建议核实下数据库和驱动的版本!
if(conn!=null){
conn.close();
}
if(pst!=null){
pst.close();
}
if(rs!=null){
rs.close();
} 这里也要改一下,要反过来
[quote="cnzxp521"]if(conn!=null){
conn.close();
}
if(pst!=null){
pst.close();
}
if(rs!=null){
rs.close();
} 这里也要改一下,要反过来[/quote]
顺序都不对
反了!~~~
[code="java"]public static void main(String[] args) finally{
try {
if(conn!=null){
conn.close();
}
if(pst!=null){
pst.close();
}
if(rs!=null){
rs.close();
}
} catch (Exception e) {
}
}
}[/code]
只需要conn.close();就可以了,关闭Connection会关闭该连接下资源
用stringbuilder,特别是希望转换成string 变成final的,即这句,用一个stringbuilder到string的转换。
你用的是数据库的函数,然后你在java中给它赋值,有可能是并发的问题,对与这个问题,建议sql中的参数的传参不要使用“?”号,和什么stringbuilder毛关系没有。
显示是连接未关闭,建议使用组件。关闭下再试试