socket服务程序是由我搭建的一个socekt框架的一部分功能负责,该框架支持阻塞式的socket通讯,支持长连接和短连接两种方式,多线程并发处理消息收发,数据库操作使用apache开源项目torque,在各省平台中使用时,在一些业务量大的省公司平台上,出现了DBCP数据库连接池无法及时回收连接的情况,造成socket服务程序无法提供服务,为了解决该问题,修改torque源码,实现对C3P0数据库连接池的支持,代码升级后,均未再现上述问题。
torque支持C3P0:
1、下载C3P0:c3p0-0.9.1.2.jar、c3p0-oracle-thin-extras-0.9.1.2.jar
2、继承AbstractDataSourceFactory实现基于C3P0数据库连接池的工厂类,编译后打包新的jar包
3、修改torque.properties,将连接池配置改为C3P0方式
4、将涉及包和配置文件放入工程
C3P0DataSourceFactory.java源码:
package org.apache.torque.dsfactory; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import javax.sql.ConnectionPoolDataSource; import javax.sql.DataSource; import org.apache.commons.configuration.Configuration; import com.mchange.v2.c3p0.ComboPooledDataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.torque.Torque; import org.apache.torque.TorqueException; /** * A factory that looks up the DataSource using the JDBC2 pool methods. * * @author John McNally * @author Henning P. Schmiedehausen * @version $Id: C3P0DataSourceFactory.java 476550 2006-11-18 16:08:37Z tfischer $ */ public class C3P0DataSourceFactory extends AbstractDataSourceFactory { /** The log. */ private static Log log = LogFactory.getLog(C3P0DataSourceFactory.class); /** The wrappedDataSource
. */ private ComboPooledDataSource ds = null; /** * @see org.apache.torque.dsfactory.DataSourceFactory#getDataSource */ public DataSource getDataSource() { return ds; } /** * @see org.apache.torque.dsfactory.DataSourceFactory#initialize */ public void initialize(Configuration configuration) throws TorqueException { log.debug("Starting initialize ----------- "); super.initialize(configuration); ComboPooledDataSource dataSource = initJdbc2Pool(configuration); this.ds = dataSource; } /** * Initializes the Jdbc2PoolDataSource. * * @param configuration where to read the settings from * @throws TorqueException if a property set fails * @return a configuredJdbc2PoolDataSource
*/ private ComboPooledDataSource initJdbc2Pool(Configuration configuration) throws TorqueException { log.debug("Starting initJdbc2Pool"); Configuration c = Torque.getConfiguration(); ComboPooledDataSource dataSource = new ComboPooledDataSource(); if (c == null || c.isEmpty()) { log.warn("Global Configuration not set," + " no Default pool data source configured!"); } else { Configuration conf = c.subset(DEFAULT_POOL_KEY); applyConfiguration(conf, dataSource); } //init 数据库连接 Configuration connConf = configuration.subset(CONNECTION_KEY); applyConfiguration(connConf, dataSource); //init 数据库连接池 Configuration conf = configuration.subset(POOL_KEY); applyConfiguration(conf, dataSource); return dataSource; } /** * Closes the pool associated with this factory and releases it. * @throws TorqueException if the pool cannot be closed properly */ public void close() throws TorqueException { try { ds.close(); } catch (Exception e) { log.error("Exception caught during close()", e); throw new TorqueException(e); } ds = null; } }
torque.properties 配置文件:
引用
# -------------------------------------------------------------------
# $Id: Torque.properties,v 1.11.2.2 2004/08/24 04:14:32 seade Exp $
#
# This is the configuration file for Torque.
#
# Note that strings containing "," (comma) characters must backslash
# escape the comma (i.e. '\,')
#
# -------------------------------------------------------------------
torque.applicationRoot = .
# -------------------------------------------------------------------
#
# L O G G I N G
#
# -------------------------------------------------------------------
# We use Log4J for all Torque logging and we embed the log4j
# properties within our application configuration.
# -------------------------------------------------------------------
# This first category is required and the category
# must be named 'default'. This is used for all logging
# where an explicit category is not specified.
log4j.category.org.apache.torque = ALL, org.apache.torque
log4j.appender.org.apache.torque = org.apache.log4j.FileAppender
log4j.appender.org.apache.torque.layout = org.apache.log4j.PatternLayout
log4j.appender.org.apache.torque.layout.conversionPattern = %d [%t] %-5p %c - %m%n
log4j.appender.org.apache.torque.append = false
# -------------------------------------------------------------------
#
# T O R Q U E P R O P E R T I E S
#
# -------------------------------------------------------------------
# These are your database settings. Look in the
# org.apache.torque.pool.* packages for more information.
#
# The parameters to connect to the default database. You MUST
# configure these properly.
# -------------------------------------------------------------------
torque.database.default=ups
torque.database.ups.adapter=oracle
# # Using commons-dbcp
#torque.dsfactory.yf.factory=org.apache.torque.dsfactory.SharedPoolDataSourceFactory
#torque.dsfactory.yf.pool.maxIdle=8
#torque.dsfactory.yf.pool.maxActive=10
#torque.dsfactory.yf.pool.testOnBorrow=true
#torque.dsfactory.yf.pool.validationQuery=select * from dual
#torque.dsfactory.yf.connection.driver = oracle.jdbc.driver.OracleDriver
#torque.dsfactory.yf.connection.url = jdbc:oracle:thin:@10.7.118.55:1521:shup
#torque.dsfactory.yf.connection.user = shup
#torque.dsfactory.yf.connection.password = shup
# # Using c3p0
torque.dsfactory.ups.factory=org.apache.torque.dsfactory.C3P0DataSourceFactory
#
torque.dsfactory.ups.pool.acquireIncrement=3
#
torque.dsfactory.ups.pool.acquireRetryAttempts=30
#
#torque.dsfactory.ups.pool.acquireRetryDelay=1000
#
torque.dsfactory.ups.pool.checkoutTimeout=30000
#
torque.dsfactory.ups.pool.initialPoolSize=3
#
torque.dsfactory.ups.pool.maxIdleTime=0
#
torque.dsfactory.ups.pool.maxPoolSize=20
#
torque.dsfactory.ups.pool.maxStatements=150
torque.dsfactory.ups.pool.maxStatementsPerConnection=0
#
torque.dsfactory.ups.pool.numHelperThreads=3
#
torque.dsfactory.ups.pool.idleConnectionTestPeriod=600
#
torque.dsfactory.ups.pool.preferredTestQuery=select * from dual
#ups connnection
torque.dsfactory.ups.connection.driverClass = oracle.jdbc.driver.OracleDriver
torque.dsfactory.ups.connection.jdbcUrl = jdbc:oracle:thin:@10.7.118.55:1521:shup
torque.dsfactory.ups.connection.user = shup
torque.dsfactory.ups.connection.password = shup
# Determines if the quantity column of the IDBroker's id_table should
# be increased automatically if requests for ids reaches a high
# volume.
torque.idbroker.clever.quantity=false
# Determines whether the managers cache instances of the business objects.
# And also whether the MethodResultCache will really cache results.
torque.manager.useCache = true