c3p0 數(shù)據(jù)庫連接池如何正確地關(guān)閉資源?

一.問題分析
關(guān)于c3p0數(shù)據(jù)庫連接池的資源的關(guān)閉是一個(gè)很重要的問題,但是資源的關(guān)閉不僅僅是只調(diào)用close()方法,將鏈接放入池中那么簡單,如果你不考慮數(shù)據(jù)源DataSource的關(guān)閉,那么你的Demo將在很少的數(shù)據(jù)庫交互之后報(bào)出“too many connections”。下面先看這樣一些代碼(注:測(cè)試程序我也就不按照正確的開發(fā)模式寫代碼了):
CreateConnection.java(本文討論的重點(diǎn)在這里)
public class CreateConnection {
private ComboPooledDataSource dataSource=new ComboPooledDataSource("mysql");
public Connection getConnection(){
Connection conn=null;
try {
conn=dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
public DataSource getDataSource() {
return dataSource;
}
public void closeConn(Connection conn){
try {
if(conn!=null && conn.isClosed()){
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}testDao.java
public class testDao {
public int reginster (String username,String pwd){
CreateConnection c=new CreateConnection();
Connection conn=c.getConnection();
int i=0;
String sql="insert into user(username,pwd)values(?,?)";
try {
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1,username);
ps.setString(2,pwd);
i=ps.executeUpdate();
}catch (Exception ex){
ex.printStackTrace();
}finally{
try {
c.closeConn(conn);
}catch (Exception ex){
ex.printStackTrace();}
}
return i;
}
}testServlet.java
public class testServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username=request.getParameter("username");
String pwd=request.getParameter("pwd");
testDao td=new testDao();
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
int i=td.reginster(username,pwd);
if(i==1){
System.out.println("------------------------test");
response.getWriter().print("<script language='javascript'>alert('注冊(cè)成功?。?!');history.back(-1)</script>");
}else{
response.getWriter().print("<script language='javascript'>alert('注冊(cè)失?。。?!');history.back(-1)</script>");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}login.jsp
<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%>
<html>
<head>
<title>注冊(cè)</title>
</head>
<body>
<form action="bluemsun/testServlet" method="post">
用戶名:<input type="text" name="username"/><br>
密碼:<input type="password" name="pwd"/>
<input type="submit" value="注冊(cè)"/>
</form>
</body>
</html>上邊程序在進(jìn)行多次交互之后會(huì)報(bào)出“too many connections”的錯(cuò)誤,原因分析如下:原因就在于程序只將鏈接放回了鏈接池使其處于空閑狀態(tài),但是卻沒有關(guān)閉dataSource , 這就導(dǎo)致目前dataSource中的初始化鏈接一直處于鏈接池中,當(dāng)下一次交互開始后又重新創(chuàng)建了新的dataSource,而下一次的dataSource還是不能被關(guān)閉,就這樣每次都會(huì)累積不能被重用的鏈接,假如在配置時(shí)連接池的初始鏈接至配置數(shù)時(shí)100,而數(shù)據(jù)庫的最大鏈接數(shù)是1000,那么在經(jīng)過10次交互后會(huì)出現(xiàn)“too many connections”的錯(cuò)誤。然而當(dāng)把資源關(guān)閉的方法修改成如下的方法時(shí)就會(huì)發(fā)現(xiàn)永遠(yuǎn)不會(huì)報(bào)出”too many connections”的錯(cuò)誤:
public void closeConn(Connection conn){
try {
if(conn!=null && conn.isClosed()){
conn.close();
}
datasource.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
datasource.close();
} catch (SQLException e) {
e.printStackTrace();
}
}上邊貼出來的方法時(shí)將DataSource也進(jìn)行了關(guān)閉。
二.方法改進(jìn)
通過上邊的分析,我們基本知道了問題出現(xiàn)的原因了,接下來就是改進(jìn)連接池的使用了,先貼一下改進(jìn)的代碼:
public class C3P0Util {
private static DataSource dataSource=null;
static{
dataSource=new ComboPooledDataSource("mysql1");
}
/**
* 獲取數(shù)據(jù)庫連接
* @return
*/
public static Connection getConnection(){
Connection conn=null;
try {
conn=dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
public static DataSource getDataSource() {
return dataSource;
}
/**
*
* @param conn
*/
public static void closeConn(Connection conn){
try {
if(conn!=null && conn.isClosed()){
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}從上邊程序中我們可以看出,是把所有的資源都用static描述,也就是把所有資源都交給了類,這樣做的好處是,每次交互都是共享C3P0Util類的datasource資源,不需要每次創(chuàng)建和關(guān)閉datasource資源,真正體現(xiàn)出了鏈接池的‘池’的特性。
出處:csdn.net/qq_40400960/article/details/80446572
關(guān)注GitHub今日熱榜,專注挖掘好用的開發(fā)工具,致力于分享優(yōu)質(zhì)高效的工具、資源、插件等,助力開發(fā)者成長!
點(diǎn)個(gè)在看 你最好看

