0 0

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都不是绝对的吧。。。看情况使用不就行了。。
DAO 
2011年11月29日 09:40

14个答案 按时间排序 按投票排序

0 0

采纳的答案

①:服务器的并发连接数超过了其承载量,服务器会将其中一些连接Down掉;

Oracle的并发数是否有关?去调一下数据库参数吧

2011年11月29日 16:02
0 0

你用的是数据库的函数,然后你在java中给它赋值,有可能是并发的问题,对与这个问题,建议sql中的参数的传参不要使用“?”号,和什么stringbuilder毛关系没有。

2011年11月30日 17:17
0 0

* 对于这个sql语句使用"+"拼接的可读性更好(实际上还是stringbuilder),

用stringbuilder,特别是希望转换成string 变成final的,即这句,用一个stringbuilder到string的转换。

2011年11月29日 16:37
0 0


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
0 0

cnzxp521 写道
if(conn!=null){ 
                    conn.close(); 
                } 
                if(pst!=null){ 
                    pst.close(); 
                } 
                if(rs!=null){ 
                    rs.close(); 
                } 这里也要改一下,要反过来

顺序都不对
反了!~~~

2011年11月29日 09:40
0 0

if(conn!=null){ 
                    conn.close(); 
                } 
                if(pst!=null){ 
                    pst.close(); 
                } 
                if(rs!=null){ 
                    rs.close(); 
                } 这里也要改一下,要反过来

2011年11月29日 09:40
0 0

建议核实下数据库和驱动的版本!

2011年11月29日 09:40
0 0

什么啊 是那个问号的问题,那个问号貌似不能写到函数参数上。。。。。

2011年11月29日 09:40
0 0

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
0 0

貌似是关闭连接的时候有问题

2011年11月29日 09:40
0 0

另外,再看看你使用的connection关闭是不是硬关闭,如果一个环境是,一个不是,也可能出现。
或者是不是打开的链接受到限制了,在你的机器上。

2011年11月29日 09:40
0 0

首先,使用用框架(自己写的或者像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
0 0

引用
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
0 0

连接未关闭。
建议使用组件

2011年11月29日 09:40

相关推荐

    connection 和 preparedstatement 的关闭问题

    ### Connection 和 PreparedStatement 的关闭问题 在Java编程语言中,处理数据库连接及执行SQL语句时,合理地管理和释放资源是非常重要的。本文将详细介绍`Connection`和`PreparedStatement`的使用时机与关闭策略,...

    PreparedStatement

    jdbc2.0版 PreparedStatement接口的用法

    如何获得PreparedStatement最终执行的sql语句

    当我们处理大量重复的SQL操作时,使用`PreparedStatement`可以避免SQL注入等问题,同时提升性能。这篇博客可能是探讨如何在实际运行中获取`PreparedStatement`最终执行的SQL语句,这对于调试和分析数据库操作非常有...

    Statement和PreparedStatement之间的区别

    在 Statement 对象中,如果用户输入的数据包含恶意代码,例如 Drop 表名,可能会导致数据库安全问题。而PreparedStatement对象则可以避免这种情况,因为它将用户输入的数据作为参数传入,而不是将其直接嵌入到SQL...

    练习3:使用PreparedStatement插入宠物信息.zip

    可能还会涉及到错误处理和异常捕获,确保程序在遇到问题时能够优雅地退出。 通过这个练习,你可以深入理解PreparedStatement的用法,以及如何安全地插入数据到数据库。同时,这也是一个很好的机会去学习数据库连接...

    PreparedStatement 向数据库插入时间方法

    然而,在处理日期和时间类型的数据时,可能会遇到一些问题。例如,当我们尝试使用`java.util.Date`对象将日期传递给`PreparedStatement`的`setDate()`方法时,程序可能会抛出异常。这是因为`setDate()`方法期望的是`...

    PreparedStatement详细用法

    ### PreparedStatement的详细用法及其优势 #### 一、概述 `PreparedStatement`是Java JDBC API中的一个关键类,用于执行预编译的SQL语句。它继承自`Statement`类,并在其基础上提供了更多的功能和优化。在Java应用...

    PreparedStatement 详细用法

    ### PreparedStatement 详细用法 #### 一、简介 在Java编程语言中,`PreparedStatement`是`java.sql`包中的一个接口,它继承自`Statement`类,并提供了预编译SQL语句的功能。预编译SQL语句的主要优势在于提高了...

    JDBC基础教程之PreparedStatement.doc

    ### JDBC基础教程之PreparedStatement知识点详解 #### 一、概述 `PreparedStatement`是Java数据库连接(JDBC)API中的一种重要接口,它继承自`Statement`接口,并在其基础上进行了扩展和优化。`PreparedStatement`...

    PreparedStatement和Statement

    在Java编程中,数据库操作是常见任务之一,而`PreparedStatement`和`Statement`是Java JDBC(Java Database Connectivity)中用于执行SQL语句的两种主要接口。它们都是`java.sql`包下的类,用来与数据库进行交互,但...

    关于PreparedStatement插入Date类型值的方法.txt

    ### 关于PreparedStatement插入Date类型值的方法 在Java编程语言中,使用`...此外,还应注意处理好时区问题,确保数据的准确性。通过正确使用这些方法,可以有效地提高应用程序的性能并增强其安全性。

    java中PreparedStatement和Statement的区别

    Java 中 PreparedStatement 和 Statement 的区别 Java 中的 PreparedStatement 和 Statement 都是用于执行 SQL 语句的接口,但是它们之间存在一些关键的区别。 首先,从数据库执行 SQL 语句的角度来看,使用 ...

    PreparedStatement接口

    NULL 博文链接:https://chaoyi.iteye.com/blog/2088080

    MySql练习3:使用PreparedStatement插入宠物信息.zip

    MySql练习3:使用PreparedStatement插入宠物信息.zip MySql练习3:使用PreparedStatement插入宠物信息.zip MySql练习3:使用PreparedStatement插入宠物信息.zip

    【性能】JDBC PreparedStatement和连接池PreparedStatement Cache学习记录

    在Java的数据库编程中,`JDBC PreparedStatement`和连接池中的`PreparedStatement Cache`是两个非常重要的概念,它们对于提升应用程序的性能和效率有着显著的作用。本文将深入探讨这两个主题,并结合Oracle数据库的...

    JDBC中PreparedStatement接口提供的execute、executeQuery和executeUpdate之间的区别及用法

    JDBC 中 PreparedStatement 接口提供的 execute、executeQuery 和 executeUpdate 之间的区别及用法 JDBC 中的 PreparedStatement 接口提供了三种执行 SQL 语句的方法:executeQuery、executeUpdate 和 execute。...

    JAVA的JDBC学习遇到的问题1

    这篇博客"JAVA的JDBC学习遇到的问题1"可能是作者在深入学习JDBC时遇到的一些常见挑战和解决方法的记录。虽然没有具体的描述内容,我们可以根据一般的学习路径来探讨JDBC相关的知识点。 1. **JDBC基本概念**:首先,...

    JSP中的PreparedStatement对象操作数据库的使用教程

    为了高效且安全地与数据库进行交互,Java提供了一套成熟的API,其中PreparedStatement对象便是核心组件之一。PreparedStatement继承自Statement接口,但它对数据库操作进行了更高级的封装,提供了预编译语句的能力。...

Global site tag (gtag.js) - Google Analytics