`
hunter090730
  • 浏览: 195275 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

多线程与连接池的应用

 
阅读更多

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

环境: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后,问题就解决了。
分享到:
评论
2 楼 hunter090730 2012-02-22  
将hour改为SECOND后,问题就解决了.
但过了一段时间之后又出现该问题了,说明真正导致此问题的原因尚未找到。
后来仔细地阅读了一下代码:
错误的真正原因在于我的线程在归还conn pool.设置了一个条件
【即只在(runflag >0)才归还到conn pool,且在第二个try{}catch里面才有finally{}。】
导致connection没有如期放到conn pool中导致connection泄漏。
而当我原来的程序跑完之后我程序会自动将runflag =0,
由于在runflag =0这段期间内,程序并没有归还到缓冲池,导致在我的处理过程中过程中有connection泄漏,那么一段时间后,就会出现这个问题。
这确实是一个隐藏很深的Bug,解决办法是:
原来有两个try{}catch,而只有最后一个才有
finally{
//才归还到缓冲池
ds.close(conn);
}
将原来的两个try{}catch,合并成一个,无论runflag条件如何都将connection归还到
conn pool.
1 楼 hunter090730 2011-12-15  
后来又加了一个线程,在加的那支线程上系统报如下错误:
++++++java.sql.SQLException: An attempt by a client to checkout a Connection has timed out.
经过修改连接池配置文件问题得以解决:
主要将pool放大
<property name="initialPoolSize">25</property>
<property name="minPoolSize">20</property>
<property name="maxPoolSize">50</property>
<property name="acquireIncrement">18</property>
<property name="checkoutTimeout">18000</property>

相关推荐

    Java网络编程-多线程,连接池

    Java网络编程是构建分布式应用程序的关键技术,特别是在服务器端开发中,多线程和连接池是其核心概念。本文将深入探讨这两个主题,并结合文件传输的实际应用进行讲解。 首先,我们来理解多线程。在Java中,多线程...

    Unidac连接池

    此外,Unidac还支持多线程环境下的连接池管理,确保在并发环境中每个线程都能安全地获取和释放连接。这通过内部的锁机制和线程同步来实现,避免了竞态条件和资源冲突。 在实际开发中,使用Unidac连接池需要注意以下...

    cpp-Odyssey先进的多线程PostgreSQL连接池和请求路由器

    《cpp-Odyssey:先进的多线程PostgreSQL连接池与请求路由器详解》 在现代的高性能Web服务中,数据库连接管理是系统性能的关键因素之一。cpp-Odyssey项目,作为一个高级的多线程PostgreSQL连接池和请求路由器,旨在...

    socket线程连接池实例

    线程连接池是一种多线程编程中的资源管理技术,用于复用已创建的线程,避免频繁地创建和销毁线程带来的开销。在高并发场景下,线程连接池能显著提高系统性能。Java中常用的线程池实现有`java.util.concurrent`包下的...

    线程池和mysql连接池的实现

    线程池和MySQL连接池是两种重要的资源管理技术,在多线程编程和数据库操作中扮演着关键角色。本文将详细探讨这两个概念,并结合在Ubuntu 12.04环境下使用C++实现线程池和MySQL连接池的方法。 线程池是一种优化并发...

    okhttp中连接池实现

    5. **并发控制**:OkHttp的连接池支持多线程并发访问。每个连接在被多个请求共享时,会进行同步控制,确保同一时刻只有一个请求在使用该连接,以避免数据冲突。 6. **超时设置**:OkHttp允许开发者自定义请求的超时...

    C#高效数据库连接池源码

    - **线程安全**:在多线程环境下,连接池必须确保并发安全,防止数据竞争和同步问题。 6. **性能优化**: - **最小/最大连接数**:设置合适的最小和最大连接数,平衡资源使用和性能需求。 - **连接检测**:定期...

    基于嵌入式SQL的数据库连接池应用技术研究.pdf

    《基于嵌入式SQL的数据库连接池应用技术研究》探讨了在多层体系结构的应用程序环境中,如何通过数据库连接池技术提升系统性能和资源利用效率。本文主要关注的关键技术包括PL/SQL、多线程以及数据库连接池。 1. PL/...

    JAVA多线程实现数据库之间的数据互导、连接池、及多表插入数据库功能

    本主题聚焦于如何利用多线程实现在不同数据库间的数据互导,以及结合连接池技术来优化数据库操作,并实现多表插入功能。我们将深入探讨以下几个核心知识点: 1. **Java多线程**: - **线程创建**:Java提供了多种...

    基于JDBC的数据库连接池技术研究与应用

    《基于JDBC的数据库连接池技术研究与应用》 在当今互联网时代,Web应用程序的开发已经从传统的桌面应用转向了基于B/S架构的模式。Java的Servlet+JSP+JavaBean技术因其跨平台、安全、高效和可移植的特性,成为了开发...

    多线程下mysql连接数过多解决demo

    在多线程环境中,MySQL连接数过多的问题是一个常见的性能瓶颈,尤其在高并发的应用场景下。这通常是由于每个线程创建一个独立的数据库连接导致的,当并发线程数量增加时,连接池中的连接数量也随之增加,如果超过...

    连接池连接池连接池

    2. **请求连接**:当应用程序需要与数据库交互时,它向连接池申请一个连接,而不是直接创建新的连接。如果池中有空闲连接,就直接分配;如果没有,可能需要等待其他线程归还连接或者达到最大连接数时拒绝新请求。 3....

    socket 客户端连接池实现

    5. 线程安全:在多线程环境中,连接池的创建、分配和回收操作必须是线程安全的,防止数据竞争和死锁。 在Java中,可以使用Apache Commons Pool库来实现Socket连接池,或者自定义一个基于LinkedList或...

    Java jdbc数据库连接池总结

    1. 并发问题:为了使连接管理服务具有最大的通用性,必须考虑多线程环境,即并发问题。这可以通过使用 synchronized 关键字来确保线程的同步。 2. 多数据库服务器和多用户:对于大型的企业级应用,常常需要同时连接...

    Springboot多连接池+websocket

    本项目涉及的关键技术是“Springboot多连接池”和“WebSocket”,这两个概念都是现代Web应用程序的重要组成部分。 首先,让我们来理解Spring Boot中的多连接池。在处理大量并发请求时,数据库连接池是必不可少的,...

    vs2003-hiredis-vc++客户端连接池,线程安全

    在IT行业中,开发高效、可靠的分布式系统常常需要与数据库进行交互,而Redis作为一个高性能的键值存储...通过使用连接池,它能够在多线程环境下优化对Redis服务器的访问,同时降低了资源消耗,提升了应用的响应速度。

    oracle 数据库,在C++中用连接池实现高速连接与访问.rar

    3. 异步操作:考虑使用异步API或多线程技术,让数据库操作和应用逻辑并行执行,提高整体性能。 4. SQL优化:避免全表扫描,使用索引,减少JOIN操作,提升SQL执行效率。 总结,结合Oracle数据库和C++的连接池技术,...

    Socket连接池的简单应用

    Socket连接池是一种高效且实用的技术,尤其适用于需要频繁与服务器交互的应用场景。通过合理设计和实现连接池,不仅可以显著提高系统的性能和稳定性,还能有效降低服务器资源的消耗。在未来开发网络应用时,不妨考虑...

    DELPHI DataSnapXE连接池类

    当应用程序需要与数据库建立连接时,而不是每次都创建新的连接,它会从连接池中获取一个已存在的连接。这样可以避免频繁地打开和关闭连接带来的开销,提高系统的整体性能。 DBXPoolUnit.pas 和 UniPoolUnit.pas ...

Global site tag (gtag.js) - Google Analytics