可持久连接吗?

atsiang 2010-03-31 10:55:40
JAVA + JDBC + MYSQL
当访问多的,报错:Data source rejected establishment of connection, message from server: "Too many connections"


怎么处理可不可持久连接?
...全文
303 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
atsiang 2010-03-31
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 dinghun8leech 的回复:]
回楼主,9L的代码大致看了下,还是有点毛病的,呵呵。
比如建立连接中的Class.forName只需调用一次即可,这步可放在这个组件的static{}中。
比如最后释放资源的方法,楼主是按照打开顺序反向关闭的,但控制上出了点问题,假如ResultSet或PreparedStatement/CallableStatement的释放出了异常,Connection就无法被关闭了。
比如sql执行异……
[/Quote]

改了一个,请指教


import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
//import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class mydb {
Connection con = null;
Statement stat = null;
ResultSet rs = null;

public CallableStatement callable = null;

static {
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
} catch (InstantiationException e1) {
e1.printStackTrace();
} catch (IllegalAccessException e1) {
e1.printStackTrace();
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
}
}

// 取得数据库连接
public Connection GetCon() {
this.Close();// 释放所有

String url = "jdbc:mysql://"; // 连接字符串

try {
con = DriverManager.getConnection(url);
return con;
} catch (SQLException e) {
// e.printStackTrace();
this.Close();
return null;
}
}

// 执行数据库查询并返回查询结果
public ResultSet Query(String sql) {
try {
con = GetCon();
stat = con.createStatement();
rs = stat.executeQuery(sql);
return rs;
} catch (SQLException e) {
// e.printStackTrace();
this.Close();
return null;
}
}

// 执行存储过程并返回参数
public CallableStatement CallProcess(String strProc) {
try {
con = GetCon();
callable = con.prepareCall("{ call " + strProc + "}");
return callable;
} catch (Exception ex) {
// ex.printStackTrace();
this.Close();
return null;
}
}

// 执行数据库更新
public void Update(String sql) {
try {
con = GetCon();
stat = con.createStatement();
stat.executeUpdate(sql);
} catch (Exception ex) {
// ex.printStackTrace();
this.Close();
}
return;
}

// 关闭数据库连接
public void Close() {
try {
if (rs != null)
rs.close();
} catch (Exception ex) {
// ex.printStackTrace();
}

try {
if (stat != null)
stat.close();
} catch (Exception ex) {
// ex.printStackTrace();
}

try {
if (callable != null)
callable.close();
} catch (Exception ex) {
// ex.printStackTrace();
}

try {
if (con != null)
con.close();
} catch (Exception ex) {
// ex.printStackTrace();
}

return;
}

}
atsiang 2010-03-31
  • 打赏
  • 举报
回复
PreparedStatement
怎么改
xuhesheng 2010-03-31
  • 打赏
  • 举报
回复
你如果一定要建立单例模式的话
可以将建立的部分按照单例模式去处理
问题是你如何关闭
当然
你可以在代码里写
Connection con = MySingleton.getConnection(url,username,password);
然后执行查询什么的
然后MySingleton.closeConnection();//该处可在关闭服务器的时候执行

但是你若用单例模式的话
虽然new出来的只有一个
但每次只能有一个人在使用的

两个人以及以上的时候就一定会有人在等

所以不建议用单例模式

所以还不如每次用完就释放关闭
所以也就是你现在代码还是比较好的

但是也是人多的时候只有固定的那些连接可以使用
使用PreparedStatement的话
可以稍微缓解下

但话说回来
你还是修改数据库本身的连接数量为好
最大是50
xuhesheng 2010-03-31
  • 打赏
  • 举报
回复
你如果一定要建立单例模式的话
可以将建立的部分按照单例模式去处理
问题是你如何关闭
当然
你可以在代码里写
Connection con = MySingleton.getConnection(url,username,password);
然后执行查询什么的
然后MySingleton.closeConnection();//该处可在关闭服务器的时候执行

但是你若用单例模式的话
虽然new出来的只有一个
但每次只能有一个人在使用的

两个人以及以上的时候就一定会有人在等

所以不建议用单例模式

所以还不如每次用完就释放关闭
所以也就是你现在代码还是比较好的

但是也是人多的时候只有固定的那些连接可以使用
使用PreparedStatement的话
可以稍微缓解下

但话说回来
你还是修改数据库本身的连接数量为好
最大是50
dinghun8leech 2010-03-31
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 atsiang 的回复:]
贴出来了,目的是用这个类,只会有一个连接产生.
[/Quote]
将生成连接的逻辑放在这个类的构造方法内,每实例化一个此类实例,都将只生成一条连接实例作为这个类的类变量。
dinghun8leech 2010-03-31
  • 打赏
  • 举报
回复
回楼主,9L的代码大致看了下,还是有点毛病的,呵呵。
比如建立连接中的Class.forName只需调用一次即可,这步可放在这个组件的static{}中。
比如最后释放资源的方法,楼主是按照打开顺序反向关闭的,但控制上出了点问题,假如ResultSet或PreparedStatement/CallableStatement的释放出了异常,Connection就无法被关闭了。
比如sql执行异常,建议不要接住,抛向调用端,因为在当前这一层我们没办法对这个异常作出有效处理(实际上调用端也没法处理,顶多记录日志或事务操作),因此需要通知调用端。
-------------------
Connection实例使用单例进行维护显然是不可取的,但楼主所写的这个组件做成单例我个人觉得也不合适。在每个用到的地方都实例化这个组件,将会得到不同的连接和相关的操作组件、数据集组件实例,保证了一定的安全性。
xuhesheng 2010-03-31
  • 打赏
  • 举报
回复
PreparedStatement 就是只产生一个连接的啊
只要不超时
都是同一个连接的
huosidun0302 2010-03-31
  • 打赏
  • 举报
回复
你去查一下单例模式怎么写,超级简单,意思就是只能创造一个对象,想hibernate中的SessionFactory或者是JDBC中的Connection都是重量级的对象.你反复的创造这些对象是有问题的.所以写成单例模式.构造方法private.只有一个实例.想Connection每次只去get方法获得就可以.不能总创建出新的.应该就是这个问题.去写一个JdbcUtil类,把你上面那些代码给封装起来
ACMAIN_CHM 2010-03-31
  • 打赏
  • 举报
回复
打开connection 后有没有 set connection = null : (这个是C#中的语法,JAVA中你需要销毁对象才会释放连接)
atsiang 2010-03-31
  • 打赏
  • 举报
回复
贴出来了,目的是用这个类,只会有一个连接产生.
xuhesheng 2010-03-31
  • 打赏
  • 举报
回复
我也知道你像使用单例模式创建connection跟数据库交互
所以推荐你写JDBC代码的时候用那个的

不如你把创建连接的那些代码贴出来看看
然后一起研究
atsiang 2010-03-31
  • 打赏
  • 举报
回复


import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
//import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class mydb {
Connection con = null;
Statement stat = null;
//PreparedStatement pstat = null;
ResultSet rs = null;

public CallableStatement callable = null;

// 取得数据库连接
public Connection GetCon() {

try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
} catch (InstantiationException e1) {
e1.printStackTrace();
} catch (IllegalAccessException e1) {
e1.printStackTrace();
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
}

String url = "jdbc:mysql://"; //连接字符串

try {
con = DriverManager.getConnection(url);
} catch (SQLException e) {
e.printStackTrace();
}

return con;
}

// 执行数据库查询并返回查询结果
public ResultSet Query(String sql) {
try {
con = GetCon();
stat = con.createStatement();
rs = stat.executeQuery(sql);
} catch (SQLException e) {
e.printStackTrace();
}

return rs;
}

// 执行存储过程并返回参数
public CallableStatement CallProcess(String strProc) {
try {
con = GetCon();
callable = con.prepareCall("{ call " + strProc + "}");
} catch (Exception ex) {
ex.printStackTrace();
}

return callable;
}

// 执行数据库更新
public void Update(String sql) {
try {
con = GetCon();
stat = con.createStatement();
stat.executeUpdate(sql);
} catch (Exception ex) {
ex.printStackTrace();
}
}

// 关闭数据库连接
public void Close() {
try {
if (rs != null)
rs.close();
if (stat != null)
stat.close();
//if (pstat != null)
// pstat.close();
if (callable != null)
callable.close();
if (con != null)
con.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}


不知道怎么改
atsiang 2010-03-31
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 dinghun8leech 的回复:]
楼主希望将单例用在jdbc中的哪个环节?
[/Quote]

创建Connection
atsiang 2010-03-31
  • 打赏
  • 举报
回复
xuhesheng,不太明白
dinghun8leech 2010-03-31
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 atsiang 的回复:]
有人说用Singleton设计模式,怎么弄好
[/Quote]
楼主希望将单例用在jdbc中的哪个环节?
xuhesheng 2010-03-31
  • 打赏
  • 举报
回复
单例模式的话
就是用那个parerparedStatement去建立连接吧
而不是Statement
(可能拼写上有错误)
为了这个数据库自定义一个单例模式来
有点不必要
JDBC里提供了相关的方法
parerparedStatement就是如果你已经有一个连接了
那么就使用该连接与数据库打交道
否则主动创建一个(此时与Statement一样)
它比Statement好在不是每次都创建

我想这样应该能缓解问题
bayougeng 2010-03-31
  • 打赏
  • 举报
回复
试试用连接池。
atsiang 2010-03-31
  • 打赏
  • 举报
回复
有人说用Singleton设计模式,怎么弄好
dinghun8leech 2010-03-31
  • 打赏
  • 举报
回复
[Quote=引用楼主 atsiang 的回复:]
JAVA + JDBC + MYSQL
当访问多的,报错:Data source rejected establishment of connection, message from server: "Too many connections"
怎么处理可不可持久连接?
[/Quote]
使用mysql的配置向导,将最大连接数调大一些。
mysql默认会将连续8小时没有操作的连接关掉,将需要重新连接。
其他的看楼下。
xuhesheng 2010-03-31
  • 打赏
  • 举报
回复
too many connection
不是这么理解的吧

你为什么一定要每一个都建立一个connection呢
可以使用已有的

java连接的时候有这样的函数、
pararedStatement吧
去试试吧
祝你成功
加载更多回复(5)

67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧