可持久连接吗?

时间:2022-10-14 22:47:04
JAVA + JDBC + MYSQL
当访问多的,报错:Data source rejected establishment of connection,  message from server: "Too many connections"


怎么处理可不可持久连接?

25 个解决方案

#1


too many connection
不是这么理解的吧

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

java连接的时候有这样的函数、
pararedStatement吧
去试试吧
祝你成功

#2


引用楼主 atsiang 的回复:
JAVA + JDBC + MYSQL
当访问多的,报错:Data source rejected establishment of connection, message from server: "Too many connections"
怎么处理可不可持久连接?

使用mysql的配置向导,将最大连接数调大一些。
mysql默认会将连续8小时没有操作的连接关掉,将需要重新连接。
其他的看楼下。

#3


有人说用Singleton设计模式,怎么弄好

#4


试试用连接池。

#5


单例模式的话
就是用那个parerparedStatement去建立连接吧
而不是Statement
(可能拼写上有错误)
为了这个数据库自定义一个单例模式来
有点不必要
JDBC里提供了相关的方法
parerparedStatement就是如果你已经有一个连接了
那么就使用该连接与数据库打交道
否则主动创建一个(此时与Statement一样)
它比Statement好在不是每次都创建

我想这样应该能缓解问题

#6


引用 3 楼 atsiang 的回复:
有人说用Singleton设计模式,怎么弄好

楼主希望将单例用在jdbc中的哪个环节?

#7


xuhesheng,不太明白

#8


引用 6 楼 dinghun8leech 的回复:
楼主希望将单例用在jdbc中的哪个环节?


创建Connection

#9




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();
}
}
}


不知道怎么改

#10


我也知道你像使用单例模式创建connection跟数据库交互
所以推荐你写JDBC代码的时候用那个的

不如你把创建连接的那些代码贴出来看看
然后一起研究

#11


贴出来了,目的是用这个类,只会有一个连接产生.

#12


打开connection 后有没有 set connection = null : (这个是C#中的语法,JAVA中你需要销毁对象才会释放连接)

#13


你去查一下单例模式怎么写,超级简单,意思就是只能创造一个对象,想hibernate中的SessionFactory或者是JDBC中的Connection都是重量级的对象.你反复的创造这些对象是有问题的.所以写成单例模式.构造方法private.只有一个实例.想Connection每次只去get方法获得就可以.不能总创建出新的.应该就是这个问题.去写一个JdbcUtil类,把你上面那些代码给封装起来

#14


PreparedStatement 就是只产生一个连接的啊
只要不超时
都是同一个连接的

#15


回楼主,9L的代码大致看了下,还是有点毛病的,呵呵。
比如建立连接中的Class.forName只需调用一次即可,这步可放在这个组件的static{}中。
比如最后释放资源的方法,楼主是按照打开顺序反向关闭的,但控制上出了点问题,假如ResultSet或PreparedStatement/CallableStatement的释放出了异常,Connection就无法被关闭了。
比如sql执行异常,建议不要接住,抛向调用端,因为在当前这一层我们没办法对这个异常作出有效处理(实际上调用端也没法处理,顶多记录日志或事务操作),因此需要通知调用端。
-------------------
Connection实例使用单例进行维护显然是不可取的,但楼主所写的这个组件做成单例我个人觉得也不合适。在每个用到的地方都实例化这个组件,将会得到不同的连接和相关的操作组件、数据集组件实例,保证了一定的安全性。

#16


引用 11 楼 atsiang 的回复:
贴出来了,目的是用这个类,只会有一个连接产生.

将生成连接的逻辑放在这个类的构造方法内,每实例化一个此类实例,都将只生成一条连接实例作为这个类的类变量。

#17


你如果一定要建立单例模式的话
可以将建立的部分按照单例模式去处理
问题是你如何关闭
当然
你可以在代码里写
Connection con = MySingleton.getConnection(url,username,password);
然后执行查询什么的
然后MySingleton.closeConnection();//该处可在关闭服务器的时候执行

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

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

所以不建议用单例模式

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

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

但话说回来
你还是修改数据库本身的连接数量为好
最大是50

#18


你如果一定要建立单例模式的话
可以将建立的部分按照单例模式去处理
问题是你如何关闭
当然
你可以在代码里写
Connection con = MySingleton.getConnection(url,username,password);
然后执行查询什么的
然后MySingleton.closeConnection();//该处可在关闭服务器的时候执行

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

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

所以不建议用单例模式

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

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

但话说回来
你还是修改数据库本身的连接数量为好
最大是50

#19


PreparedStatement
怎么改

#20


引用 15 楼 dinghun8leech 的回复:
回楼主,9L的代码大致看了下,还是有点毛病的,呵呵。
比如建立连接中的Class.forName只需调用一次即可,这步可放在这个组件的static{}中。
比如最后释放资源的方法,楼主是按照打开顺序反向关闭的,但控制上出了点问题,假如ResultSet或PreparedStatement/CallableStatement的释放出了异常,Connection就无法被关闭了。
比如sql执行异……


改了一个,请指教


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;
}

}

#21


回楼主,同一个此组件的实例还是不要重复连接比较好,没有什么意义。
既然使用到这个组件必然要建立连接,何不将建立连接的动作置入构造方法内呢,这样还能避免连接未建立时对操作数据库方法的非法调用。

#22


引用 21 楼 dinghun8leech 的回复:
回楼主,同一个此组件的实例还是不要重复连接比较好,没有什么意义。
既然使用到这个组件必然要建立连接,何不将建立连接的动作置入构造方法内呢,这样还能避免连接未建立时对操作数据库方法的非法调用。


dinghun8leech:正是我想要的,但怎么构造,头有些晕了。

#23


引用 22 楼 atsiang 的回复:
dinghun8leech:正是我想要的,但怎么构造,头有些晕了。

呵呵,再仔细想想,多改改。
jdbc的工具集我从上培训班开始写,经历了一年多改了多次,才稍微感觉好用了些,呵呵。

#24


#25


在说些什么啊..

#1


too many connection
不是这么理解的吧

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

java连接的时候有这样的函数、
pararedStatement吧
去试试吧
祝你成功

#2


引用楼主 atsiang 的回复:
JAVA + JDBC + MYSQL
当访问多的,报错:Data source rejected establishment of connection, message from server: "Too many connections"
怎么处理可不可持久连接?

使用mysql的配置向导,将最大连接数调大一些。
mysql默认会将连续8小时没有操作的连接关掉,将需要重新连接。
其他的看楼下。

#3


有人说用Singleton设计模式,怎么弄好

#4


试试用连接池。

#5


单例模式的话
就是用那个parerparedStatement去建立连接吧
而不是Statement
(可能拼写上有错误)
为了这个数据库自定义一个单例模式来
有点不必要
JDBC里提供了相关的方法
parerparedStatement就是如果你已经有一个连接了
那么就使用该连接与数据库打交道
否则主动创建一个(此时与Statement一样)
它比Statement好在不是每次都创建

我想这样应该能缓解问题

#6


引用 3 楼 atsiang 的回复:
有人说用Singleton设计模式,怎么弄好

楼主希望将单例用在jdbc中的哪个环节?

#7


xuhesheng,不太明白

#8


引用 6 楼 dinghun8leech 的回复:
楼主希望将单例用在jdbc中的哪个环节?


创建Connection

#9




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();
}
}
}


不知道怎么改

#10


我也知道你像使用单例模式创建connection跟数据库交互
所以推荐你写JDBC代码的时候用那个的

不如你把创建连接的那些代码贴出来看看
然后一起研究

#11


贴出来了,目的是用这个类,只会有一个连接产生.

#12


打开connection 后有没有 set connection = null : (这个是C#中的语法,JAVA中你需要销毁对象才会释放连接)

#13


你去查一下单例模式怎么写,超级简单,意思就是只能创造一个对象,想hibernate中的SessionFactory或者是JDBC中的Connection都是重量级的对象.你反复的创造这些对象是有问题的.所以写成单例模式.构造方法private.只有一个实例.想Connection每次只去get方法获得就可以.不能总创建出新的.应该就是这个问题.去写一个JdbcUtil类,把你上面那些代码给封装起来

#14


PreparedStatement 就是只产生一个连接的啊
只要不超时
都是同一个连接的

#15


回楼主,9L的代码大致看了下,还是有点毛病的,呵呵。
比如建立连接中的Class.forName只需调用一次即可,这步可放在这个组件的static{}中。
比如最后释放资源的方法,楼主是按照打开顺序反向关闭的,但控制上出了点问题,假如ResultSet或PreparedStatement/CallableStatement的释放出了异常,Connection就无法被关闭了。
比如sql执行异常,建议不要接住,抛向调用端,因为在当前这一层我们没办法对这个异常作出有效处理(实际上调用端也没法处理,顶多记录日志或事务操作),因此需要通知调用端。
-------------------
Connection实例使用单例进行维护显然是不可取的,但楼主所写的这个组件做成单例我个人觉得也不合适。在每个用到的地方都实例化这个组件,将会得到不同的连接和相关的操作组件、数据集组件实例,保证了一定的安全性。

#16


引用 11 楼 atsiang 的回复:
贴出来了,目的是用这个类,只会有一个连接产生.

将生成连接的逻辑放在这个类的构造方法内,每实例化一个此类实例,都将只生成一条连接实例作为这个类的类变量。

#17


你如果一定要建立单例模式的话
可以将建立的部分按照单例模式去处理
问题是你如何关闭
当然
你可以在代码里写
Connection con = MySingleton.getConnection(url,username,password);
然后执行查询什么的
然后MySingleton.closeConnection();//该处可在关闭服务器的时候执行

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

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

所以不建议用单例模式

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

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

但话说回来
你还是修改数据库本身的连接数量为好
最大是50

#18


你如果一定要建立单例模式的话
可以将建立的部分按照单例模式去处理
问题是你如何关闭
当然
你可以在代码里写
Connection con = MySingleton.getConnection(url,username,password);
然后执行查询什么的
然后MySingleton.closeConnection();//该处可在关闭服务器的时候执行

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

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

所以不建议用单例模式

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

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

但话说回来
你还是修改数据库本身的连接数量为好
最大是50

#19


PreparedStatement
怎么改

#20


引用 15 楼 dinghun8leech 的回复:
回楼主,9L的代码大致看了下,还是有点毛病的,呵呵。
比如建立连接中的Class.forName只需调用一次即可,这步可放在这个组件的static{}中。
比如最后释放资源的方法,楼主是按照打开顺序反向关闭的,但控制上出了点问题,假如ResultSet或PreparedStatement/CallableStatement的释放出了异常,Connection就无法被关闭了。
比如sql执行异……


改了一个,请指教


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;
}

}

#21


回楼主,同一个此组件的实例还是不要重复连接比较好,没有什么意义。
既然使用到这个组件必然要建立连接,何不将建立连接的动作置入构造方法内呢,这样还能避免连接未建立时对操作数据库方法的非法调用。

#22


引用 21 楼 dinghun8leech 的回复:
回楼主,同一个此组件的实例还是不要重复连接比较好,没有什么意义。
既然使用到这个组件必然要建立连接,何不将建立连接的动作置入构造方法内呢,这样还能避免连接未建立时对操作数据库方法的非法调用。


dinghun8leech:正是我想要的,但怎么构造,头有些晕了。

#23


引用 22 楼 atsiang 的回复:
dinghun8leech:正是我想要的,但怎么构造,头有些晕了。

呵呵,再仔细想想,多改改。
jdbc的工具集我从上培训班开始写,经历了一年多改了多次,才稍微感觉好用了些,呵呵。

#24


#25


在说些什么啊..