欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

多线程与连接池的应用

程序员文章站 2022-06-03 16:21:54
...

最近,为适应业务需要,需要在原来多线程的地方改用连接池,因为在没用连接池之前服务器上老是拿不到连接。

环境:MSsqlserver 2000+JDK1.6+resin

我用的C3p0线程池(jtds驱动)

C3p0配置如下:

 

<?xml version="1.0" encoding="UTF-8"?>

<c3p0-config>

<named-config name="userApp">

<property name="driverClass">

net.sourceforge.jtds.jdbc.Driver

</property>

<property name="jdbcUrl">

jdbc:jtds:sqlserver://localhost:1433/dbname

</property>

<property name="user">sa</property>

<property name="password">pawd</property>

 

<property name="initialPoolSize">12</property>

<property name="minPoolSize">10</property>

<property name="maxPoolSize">20</property>

        <property name="acquireIncrement">8</property>

<property name="acquireRetryDelay">1000</property>

<property name="maxStatements">50</property>

<property name="maxStatementsPerConnection">10</property>

 

        <property name="idleConnectionTestPeriod">360</property>

        <property name="checkoutTimeout">1800</property>

</named-config>

</c3p0-config>

 

 

用到这个连接池的地方为:

 

package me;

 

import java.sql.Connection;

import java.sql.SQLException;

 

import com.mchange.v2.c3p0.ComboPooledDataSource;

 

public class DbConnection {

private ComboPooledDataSource dataSource;

 

private DbConnection() {

dataSource = new ComboPooledDataSource("userApp");

}

 

public  Connection getConnection() throws SQLException {

return this.dataSource.getConnection();

}

public static DbConnection getSingleDBConnection(){

return new DbConnection();

}

 

public void close(Connection conn) throws SQLException {

 

if (conn != null) {

conn.close();

System.out.println("conn======>" + conn);

 

}

 

}

 

/* public static void main(String[] args) {

DbConnection ds= getSingleDBConnection();

try {

Connection conn=ds.getConnection();

Statement stmt = conn.createStatement();

  ResultSet rs = stmt.executeQuery("select * from flagInfo");

  while (rs.next()) {

   System.out.println("标识[" + rs.getString("flag") + "] 描述["

     + rs.getString("descs") + "] maxs:[" + rs.getString("maxs"));

  }

  rs.close();

  stmt.close();

  if(conn!=null){

  conn.close();

  conn=null;

  }

  

} catch (SQLException e) {

 

e.printStackTrace();

}

}*/

}


======上面这段是OK的,之前我是这么干的:

private static ComboPooledDataSource dataSource;

static{

dataSource = new ComboPooledDataSource("userApp");

}

想的是:在我七个线程里面共用一个 dataSource,想当然的我就把申明成了一个static的,但在运行时发现当线程池里的

connection用过之后,连接池便不再自动地去拿连接了,线程也就不再运行了,当时还老报一个MS.sqlException的异常;刚开始以为是c3p0配置问题,在网上查了好久包括上到C3p0的官方网站上也没有解决这个问题。弄了两三个小时,最后我想可能是static+多线程的锁出的问题吧,第二天上班时将其改成用单例模式实现,成功解决上述问题。

主要收获两点:

1,不要过度紧张配置文件,认为那个地方没配好就导致玩不下去了,这往往会误导你解决问题的方向发生偏离。

2,要小心static,凡是定义为static的他的内容在内存中便永久性地存在了,不会再作任何改变了。

另外:对于多线程的共用对象,也更体会深刻了。对于static的一定为切加小心。

 


 

后来又加了一个线程,它的主要目的是一次性将在一个时间段里面符合条件的记录拿出来处理后并insert到sqlserver里, 算时间段关键的地方如: DATEADD(hour, 2, starttime) as batchTime from flagInfo where flag=‘...’ 程序运行一段时间自动关闭这个线程后,但当我再次启动此线程欲重新跑时,就再次报出如下错误: ++++++java.sql.SQLException: An attempt by a client to checkout a Connection has timed out. 经过分析发现,当sqlserver一次插入过多数据时,sqlserver行锁处理不过来时就报连接超时的问题了, 将hour改为SECOND后,问题就解决了。