-
PreparedStatement 偶然遇到问题10
最近做了个项目。。测了好几遍了。。。然后突然测试那边的数据库环境执行一条SQL语句不行了。报错“ java.net.SocketException: Connection reset”
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(?))
)其中F_GetChildren是一个函数,传个父节点的ID值返回所有全递归子节点。这sql语句绝对没问题,在本地和测试的查询分析器里执行是正常的。然后在本机测试了程序下可以。其他开发部门同事机子上也可以。就测试部门不可以。我把本地库分离下来附加到测试那边的环境。还是不行。我的猜测就是测试那边数据库环境出现错误了。。。但是却不知道是哪出错了。。。正要放弃时突然发现我如果不用PreparedStatement的预编译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) { } } }
异常: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
如果我屏蔽掉 pst.setInt(1,1);然后把sql语句中的问号改成1,就可以了。。。难道是我函数原因。但是在我和我同事机子上也可以啊。
函数语句: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](@Pid int) 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
问题补充:<div class="quote_title">抛出异常的爱 写道</div><div class="quote_div"> <br />把这个反过来关 试试。 <br />为什么不用框架作这东西 <br />手写jdbc好多好多年没见过了。</div> <br />抛哥反过来关也是一样。。。实际上我用的就是框架。springMVC+hibernate。。。。这个只是我自己写的测试的。。。。关键是我想知道为什么数据库放我和我同事机子上可以。。。而放在测试那边就不行了。。。。。而且测试那边不是一台机子不行是好几台机子都有这种情况。。。。。。。我和测试那边是属于同一网段的。。。。。
问题补充:可能描述的不清楚。。。我补充下。。同样的代码。同样的数据库脚本。。在我们开发这边上面代码能正常执行,而在测试那边几台机子就不行。。只有换成直接拼接SQL才行。。就在执行pst.executeQuery();时报错。我试过把我机子上数据库附加或者备份到测试那边还是不行。也看了两边的ipconfig。。。在同一网段。。。。。然后测试那边以前是可以。。现在不知道怎么回事不行了。。。。情况就是这么诡异。我感觉很大可能是环境的原因。。但是具体是数据库环境原因还是系统环境原因就不清楚了。。。
问题补充:<div class="quote_title">抛出异常的爱 写道</div><div class="quote_div">①:服务器的并发连接数超过了其承载量,服务器会将其中一些连接Down掉; <br /> <br />Oracle的并发数是否有关?去调一下数据库参数吧</div> <br />是sqlserver 2000的库。。不过这倒也是个思路。。。我看下是不是并发连接的问题。
问题补充:<div class="quote_title">redhat 写道</div><div class="quote_div"> <br />用stringbuilder,特别是希望转换成string 变成final的,即这句,用一个stringbuilder到string的转换。 </div> <br />。。。你总是关注这个干什么。。你可能认真看下我的问题描述。。再说我不是说了这个是我用于测试的代码了么。。。。实际上用string 还是stringbuilder或者是final都不是绝对的吧。。。看情况使用不就行了。。2011年11月29日 09:40
14个答案 按时间排序 按投票排序
-
采纳的答案
①:服务器的并发连接数超过了其承载量,服务器会将其中一些连接Down掉;
Oracle的并发数是否有关?去调一下数据库参数吧2011年11月29日 16:02
-
你用的是数据库的函数,然后你在java中给它赋值,有可能是并发的问题,对与这个问题,建议sql中的参数的传参不要使用“?”号,和什么stringbuilder毛关系没有。
2011年11月30日 17:17
-
* 对于这个sql语句使用"+"拼接的可读性更好(实际上还是stringbuilder),
用stringbuilder,特别是希望转换成string 变成final的,即这句,用一个stringbuilder到string的转换。2011年11月29日 16:37
-
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) { } } }
只需要conn.close();就可以了,关闭Connection会关闭该连接下资源
2011年11月29日 09:40
-
cnzxp521 写道if(conn!=null){
conn.close();
}
if(pst!=null){
pst.close();
}
if(rs!=null){
rs.close();
} 这里也要改一下,要反过来
顺序都不对
反了!~~~2011年11月29日 09:40
-
if(conn!=null){
conn.close();
}
if(pst!=null){
pst.close();
}
if(rs!=null){
rs.close();
} 这里也要改一下,要反过来2011年11月29日 09:40
-
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函数。如果只是测试,那还可以。
再看看你的网络设置吧,具体没有跟踪,只能提供一点参考意见。
呵呵,没下文了啊。
* 对于这个sql语句使用"+"拼接的可读性更好(实际上还是stringbuilder)
* 不象是 连接已经满了的问题。
* 不过确实诡异,跟踪调试下吧!
文中提到:
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(); 产生的异常,那还没有到链接关闭的执行。虽然链接关闭顺序确实搞反了。jyjava 写道貌似是关闭连接的时候有问题
* bug的可能性?
尝试:
pst.execute();
rs = pst.getResultSet();2011年11月29日 09:40
-
另外,再看看你使用的connection关闭是不是硬关闭,如果一个环境是,一个不是,也可能出现。
或者是不是打开的链接受到限制了,在你的机器上。2011年11月29日 09:40
-
首先,使用用框架(自己写的或者像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函数。如果只是测试,那还可以。
再看看你的网络设置吧,具体没有跟踪,只能提供一点参考意见。2011年11月29日 09:40
-
引用Connection reset by peer的原因:
经常出现的Connection reset by peer: 原因可能是多方面的,不过更常见的原因是:
①:服务器的并发连接数超过了其承载量,服务器会将其中一些连接Down掉;
②:客户关掉了浏览器,而服务器还在给客户端发送数据;
③:浏览器端按了Stop
try { if(conn!=null){ conn.close(); } if(pst!=null){ pst.close(); } if(rs!=null){ rs.close(); }
把这个反过来关 试试。
为什么不用框架作这东西
手写jdbc好多好多年没见过了。2011年11月29日 09:40
相关推荐
### Connection 和 PreparedStatement 的关闭问题 在Java编程语言中,处理数据库连接及执行SQL语句时,合理地管理和释放资源是非常重要的。本文将详细介绍`Connection`和`PreparedStatement`的使用时机与关闭策略,...
jdbc2.0版 PreparedStatement接口的用法
当我们处理大量重复的SQL操作时,使用`PreparedStatement`可以避免SQL注入等问题,同时提升性能。这篇博客可能是探讨如何在实际运行中获取`PreparedStatement`最终执行的SQL语句,这对于调试和分析数据库操作非常有...
在 Statement 对象中,如果用户输入的数据包含恶意代码,例如 Drop 表名,可能会导致数据库安全问题。而PreparedStatement对象则可以避免这种情况,因为它将用户输入的数据作为参数传入,而不是将其直接嵌入到SQL...
可能还会涉及到错误处理和异常捕获,确保程序在遇到问题时能够优雅地退出。 通过这个练习,你可以深入理解PreparedStatement的用法,以及如何安全地插入数据到数据库。同时,这也是一个很好的机会去学习数据库连接...
然而,在处理日期和时间类型的数据时,可能会遇到一些问题。例如,当我们尝试使用`java.util.Date`对象将日期传递给`PreparedStatement`的`setDate()`方法时,程序可能会抛出异常。这是因为`setDate()`方法期望的是`...
### PreparedStatement的详细用法及其优势 #### 一、概述 `PreparedStatement`是Java JDBC API中的一个关键类,用于执行预编译的SQL语句。它继承自`Statement`类,并在其基础上提供了更多的功能和优化。在Java应用...
### PreparedStatement 详细用法 #### 一、简介 在Java编程语言中,`PreparedStatement`是`java.sql`包中的一个接口,它继承自`Statement`类,并提供了预编译SQL语句的功能。预编译SQL语句的主要优势在于提高了...
### JDBC基础教程之PreparedStatement知识点详解 #### 一、概述 `PreparedStatement`是Java数据库连接(JDBC)API中的一种重要接口,它继承自`Statement`接口,并在其基础上进行了扩展和优化。`PreparedStatement`...
在Java编程中,数据库操作是常见任务之一,而`PreparedStatement`和`Statement`是Java JDBC(Java Database Connectivity)中用于执行SQL语句的两种主要接口。它们都是`java.sql`包下的类,用来与数据库进行交互,但...
### 关于PreparedStatement插入Date类型值的方法 在Java编程语言中,使用`...此外,还应注意处理好时区问题,确保数据的准确性。通过正确使用这些方法,可以有效地提高应用程序的性能并增强其安全性。
Java 中 PreparedStatement 和 Statement 的区别 Java 中的 PreparedStatement 和 Statement 都是用于执行 SQL 语句的接口,但是它们之间存在一些关键的区别。 首先,从数据库执行 SQL 语句的角度来看,使用 ...
NULL 博文链接:https://chaoyi.iteye.com/blog/2088080
MySql练习3:使用PreparedStatement插入宠物信息.zip MySql练习3:使用PreparedStatement插入宠物信息.zip MySql练习3:使用PreparedStatement插入宠物信息.zip
在Java的数据库编程中,`JDBC PreparedStatement`和连接池中的`PreparedStatement Cache`是两个非常重要的概念,它们对于提升应用程序的性能和效率有着显著的作用。本文将深入探讨这两个主题,并结合Oracle数据库的...
JDBC 中 PreparedStatement 接口提供的 execute、executeQuery 和 executeUpdate 之间的区别及用法 JDBC 中的 PreparedStatement 接口提供了三种执行 SQL 语句的方法:executeQuery、executeUpdate 和 execute。...
这篇博客"JAVA的JDBC学习遇到的问题1"可能是作者在深入学习JDBC时遇到的一些常见挑战和解决方法的记录。虽然没有具体的描述内容,我们可以根据一般的学习路径来探讨JDBC相关的知识点。 1. **JDBC基本概念**:首先,...
为了高效且安全地与数据库进行交互,Java提供了一套成熟的API,其中PreparedStatement对象便是核心组件之一。PreparedStatement继承自Statement接口,但它对数据库操作进行了更高级的封装,提供了预编译语句的能力。...