package java.common;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Vector;
/**
* DBコネクション管理クラス
*
*/
public class DBConnectionPool
{
/** インスタンス */
private static DBConnectionPool connectionPool = null;
/** コネクションを保持するベクトル */
private Vector connections = null;
/** 現在のコネクション数 */
int currentCount = 0;
/** 同時にデータベースに接続可能なコネクション数 */
private static final int MAX_CONNECTION = Integer.parseInt(SystemProperties.get( "MAX_CONNECTION" ));
/** 最小コネクション数 */
private static final int MIN_CONNECTION = Integer.parseInt(SystemProperties.get( "MIN_CONNECTION" ));
/** 最大待ち時間(秒)*/
private static final int CONNECTION_TIMEOUT = Integer.parseInt(SystemProperties.get( "CONNECTION_TIMEOUT" ));
/** コネクション取得待ち時間(ミリ秒) */
private static final int WAIT_TIME = Integer.parseInt(SystemProperties.get( "WAIT_TIME" ));
/** DBアクセスに必要な各値(環境に依存) */
private static final String DRIVER = SystemProperties.get( "DRIVER_CLASS_NAME" );
private static final String URL = SystemProperties.get( "URL" );
private static final String USER = SystemProperties.get( "USER" );
private static final String PASSWORD = SystemProperties.get( "PASSWORD" );
/**
* DBConnectionPool インスタンスの取得
*
* @return インスタンスを戻します。
*/
public static DBConnectionPool getInstance() throws Exception
{
if( DBConnectionPool.connectionPool == null || !DBConnectionPool.checkConnectionValidity() )
{
DBConnectionPool.connectionPool = new DBConnectionPool();
}
return DBConnectionPool.connectionPool;
}
/**
* DBConnectionPool インスタンスの生成
* ※privateなので、外部からの生成(new)は不可能
*/
private DBConnectionPool() throws Exception
{
// DBアクセスに必要な各値を設定
Class.forName( DRIVER );
connections = new Vector();
for( int i = 0; i < MIN_CONNECTION; i++ )
{
Connection connection = createConnection();
connections.add( connection );
currentCount++;
}
}
/**
* コネクションの取得
* ※取得できない場合は引数で与えられた回数だけコネクション取得待ち時間おきにトライ
*
* @param count_ コネクション取得の試行回数。
* @return コネクション(取得できなかったた場合はnul)を戻します。
* @throws SQLException
*/
public synchronized Connection getConnection( int count_ ) throws SQLException
{
// 試行回数に達した場合は null を返す
if( count_ < 1 )
{
return null;
}
// コネクションが残っていればプールから1つ取り出して提供する
if( 0 < connections.size() )
{
Connection connection = ( Connection )connections.get( 0 );
connections.remove( 0 );
return connection;
}
else if( currentCount < MAX_CONNECTION )
{
currentCount++;
return createConnection();
}
else
{
// コネクションが残っていなければXXミリ秒待機
try
{
wait( WAIT_TIME );
}
catch( Exception e )
{
e.printStackTrace();
}
// 試行回数を1つ減らして再度取得を実行
return getConnection( count_ - 1 );
}
}
/**
* コネクションの返却
*
* @param connection_ 返却するコネクション。
*/
public synchronized void releaseConnection( Connection connection_ )
{
// プールに返されたコネクションを追加
connections.add( connection_ );
}
/**
* コネクションの作成
*
* @return conn コネクション。
* @throws SQLException
*/
private Connection createConnection() throws SQLException
{
// 最大待ち時間を設定
DriverManager.setLoginTimeout( CONNECTION_TIMEOUT );
Connection conn = DriverManager.getConnection( URL, USER, PASSWORD );
return conn;
}
/**
* コネクションの有効性チェック
*
* @return trueOrFalse 真偽。
*/
private static boolean checkConnectionValidity()
{
boolean trueOrFalse = true; //戻り値
String validationQuery = "select 1"; //検証用クエリ
Connection conn = null;
Statement stmt = null;
try
{
// プールされているコネクションで検証用クエリを実行
if( 0 < connectionPool.connections.size() )
{
conn = ( Connection )connectionPool.connections.get( 0 );
connectionPool.connections.remove( 0 );
stmt = conn.createStatement();
stmt.execute( validationQuery );
}
}
catch( SQLException e )
{
// 接続エラーが発生した場合は戻り値をfalseとする
if( e.getErrorCode() == 0 && "08S01".equals( e.getSQLState() ) )
{
trueOrFalse = false;
}
}
finally
{
if( stmt != null )
{
try
{
stmt.close();
}
catch( SQLException e )
{
}
}
if( conn != null )
{
connectionPool.releaseConnection( conn );
}
}
return trueOrFalse;
}
/**
* プールされているコネクションのクローズ
*
*/
public synchronized void closeConnections()
{
Connection connection = null;
// プールからコネクションを取り出してクローズ
while( 0 < connections.size() )
{
connection = ( Connection )connections.get( 0 );
connections.remove( 0 );
if( connection != null )
{
try
{
connection.close();
connection = null;
}
catch( SQLException e )
{
// 特に何もしない
System.out.println( "DBコネクションのクローズに失敗" );
}
}
}
}
}
分享到:
相关推荐
JAVA学习中,自己学着写的一个连接池.
标题提到的“一个比较好手写连接池”指的是一个由个人或团队独立编写的、用于管理数据库连接的类库,它模仿了Tomcat连接池(Apache Commons DBCP或HikariCP)的工作原理。这种自定义连接池对于小型项目来说,可能是...
数据库连接池是Java开发中非常重要的一个概念,它在处理大量并发访问数据库的应用场景中扮演着关键角色。本文将深入探讨数据库连接池的工作原理、重要性以及如何在Java中实现一个简单的连接池。 首先,数据库连接池...
数据库连接池是Java应用程序中非常重要的一个组件,它在提高应用性能、节省系统资源方面起着关键作用。本文将深入探讨如何使用Java手写数据库连接池,并基于maven进行项目构建。我们将分析四个核心类的功能,以及...
Java手写连接池是一个编程实践,它涉及到数据库管理和优化,主要目标是提高数据库访问的效率和资源利用率。在Java中,连接池是一个管理数据库连接的系统,它预先创建一定数量的数据库连接,当应用程序需要时可以立即...
在Java中,`commons-pool`库是一个广泛使用的对象池框架,它可以用于构建各种类型的连接池,包括FTP连接池。`commons-pool`提供了基础的池化机制,开发者需要根据FTP协议实现具体的FTP连接对象和管理策略。 在实际...
连接池是在应用程序启动时创建一定数量的Socket连接,并将它们保存在一个集合中,当需要建立新的网络连接时,从池中获取一个已经建立好的连接,使用完毕后归还给池,而不是立即关闭。这样可以避免频繁的创建和销毁...
否则,连接池管理器将创建一个新的连接对象,并将其添加到连接池中。应用程序使用完毕连接后,需要将连接对象返回连接池,以便下一个应用程序可以使用。 在服务器端,连接池管理器可以在服务器启动时初始化,并在...
3. **HikariCP**:目前广泛被认为是最高效的Java连接池,其设计目标是极低的资源消耗和超快的性能。 4. **Druid**:阿里巴巴开源的数据库连接池,除了基础功能外,还提供了监控、日志、SQL解析等功能。 在自定义...
了解并正确使用MongoDB的Java连接池对于提高应用程序性能和稳定性至关重要,特别是在高并发的Web应用或大数据处理项目中。因此,深入理解连接池的工作原理和配置方法,对于任何MongoDB Java开发者来说都是必要的技能...
RabbitMQ客户连接池的Java实现。我们刚开始也是采用这种方式来实现的,但做压力测试时,发现这种每次新建Connection和新建Channel是非常耗时的,在大并发下,一般都要8毫秒左右,慢的话,好多都是几十毫秒。因此我们...
2. 借用与归还:当客户端请求到来时,服务器从连接池中取出一个已建立的Socket连接,用于处理请求。完成后,不再关闭连接,而是将其归还到池中,供后续请求使用。 3. 管理:连接池管理器负责维护池中连接的状态,...
### JAVA 使用数据库连接池连接Oracle数据库全代码解析 #### 一、概述 本文将详细介绍如何在Java项目中使用Apache DBCP(Database Connection Pool)来连接Oracle数据库,并提供完整的示例代码。通过这种方式,我们...
本文将详细介绍如何在 Java 中实现一个完整的数据库连接池,并探讨其核心概念、工作原理以及如何根据需求进行配置。 首先,我们需要理解数据库连接池的基本概念。数据库连接池是一种对象池设计模式的应用,它维护了...
解决多数据库服务器和多用户问题可以设计一个符合单例模式的连接池管理类,在连接池管理类的唯一实例被创建时读取一个资源文件,其中包含了不同的数据库连接信息。 Java JDBC 数据库连接池的优点包括: 1. 提高...
理解并正确使用Java连接池是任何涉及数据库操作的Java应用的基础,它对于优化系统性能、提高资源利用率和保证服务稳定性都有着重要作用。选择合适的连接池库并进行适当的配置,可以进一步提升系统的响应速度和并发...
Java连接池是Java应用程序中管理数据库连接的一种机制,它的出现大大提高了数据库操作的性能和效率。连接池的基本思想是预先创建一定数量的数据库连接,并将它们保存在一个池中,当应用需要时可以从池中获取一个连接...
"Java连接SAP系统所用的JCo连接池的配置和使用" Java连接SAP系统所用的JCo连接池的配置和使用是指在Java应用程序中使用JCo连接池来连接SAP R3系统的技术。JCo(Java Connector)是SAP提供的一种Java API,用于连接...
本文将深入探讨如何使用Java代码来实现一个简单的数据库连接池,并解释其核心概念和工作原理。 连接池的基本思想是维护一组预初始化的数据库连接,当应用程序需要时,可以从池中获取一个连接,使用完毕后,再归还回...