Mini Connection Pool Manager : Connection Pool « Database SQL JDBC « Java

Java
1. 2D Graphics GUI
2. 3D
3. Advanced Graphics
4. Ant
5. Apache Common
6. Chart
7. Class
8. Collections Data Structure
9. Data Type
10. Database SQL JDBC
11. Design Pattern
12. Development Class
13. EJB3
14. Email
15. Event
16. File Input Output
17. Game
18. Generics
19. GWT
20. Hibernate
21. I18N
22. J2EE
23. J2ME
24. JDK 6
25. JNDI LDAP
26. JPA
27. JSP
28. JSTL
29. Language Basics
30. Network Protocol
31. PDF RTF
32. Reflection
33. Regular Expressions
34. Scripting
35. Security
36. Servlets
37. Spring
38. Swing Components
39. Swing JFC
40. SWT JFace Eclipse
41. Threads
42. Tiny Application
43. Velocity
44. Web Services SOA
45. XML
Java Tutorial
Java Source Code / Java Documentation
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java » Database SQL JDBC » Connection PoolScreenshots 
Mini Connection Pool Manager
  
// Test program for the MiniConnectionPoolManager class.

import java.io.PrintWriter;
import java.lang.Thread;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Random;
import javax.sql.ConnectionPoolDataSource;
import biz.source_code.miniConnectionPoolManager.MiniConnectionPoolManager;

public class TestMiniConnectionPoolManager {

private static final int                  maxConnections   = 8;     // number of connections
private static final int                  noOfThreads      = 50;    // number of worker threads
private static final int                  processingTime   = 30;    // total processing time of the test program in seconds
private static final int                  threadPauseTime1 = 100;   // max. thread pause time in microseconds, without a connection
private static final int                  threadPauseTime2 = 100;   // max. thread pause time in microseconds, with a connection

private static MiniConnectionPoolManager  poolMgr;
private static WorkerThread[]             threads;
private static boolean                    shutdownFlag;
private static Object                     shutdownObj = new Object();
private static Random                     random = new Random();

private static class WorkerThread extends Thread {
   public int threadNo;
   public void run() {threadMain (threadNo)}};

private static ConnectionPoolDataSource createDataSource() throws Exception {

   // Version for H2:
      org.h2.jdbcx.JdbcDataSource dataSource = new org.h2.jdbcx.JdbcDataSource();
      dataSource.setURL ("jdbc:h2:file:c:/temp/temp_TestMiniConnectionPoolManagerDB;DB_CLOSE_DELAY=-1");

   // Version for Apache Derby:
   /*
      org.apache.derby.jdbc.EmbeddedConnectionPoolDataSource dataSource = new org.apache.derby.jdbc.EmbeddedConnectionPoolDataSource();
      dataSource.setDatabaseName ("c:/temp/temp_TestMiniConnectionPoolManagerDB");
      dataSource.setCreateDatabase ("create");
      dataSource.setLogWriter (new PrintWriter(System.out));
   */

   // Versioo for JTDS:
   /*
      net.sourceforge.jtds.jdbcx.JtdsDataSource dataSource = new net.sourceforge.jtds.jdbcx.JtdsDataSource();
      dataSource.setAppName ("TestMiniConnectionPoolManager");
      dataSource.setDatabaseName ("Northwind");
      dataSource.setServerName ("localhost");
      dataSource.setUser ("sa");
      dataSource.setPassword (System.getProperty("saPassword"));
   */

   // Version for the Microsoft SQL Server driver (sqljdbc.jar):
   /*
      // The sqljdbc 1.1 documentation, chapter "Using Connection Pooling", recommends to use
      // SQLServerXADataSource instead of SQLServerConnectionPoolDataSource, even when no
      // distributed transactions are used.
      com.microsoft.sqlserver.jdbc.SQLServerXADataSource dataSource = new com.microsoft.sqlserver.jdbc.SQLServerXADataSource();
      dataSource.setApplicationName ("TestMiniConnectionPoolManager");
      dataSource.setDatabaseName ("Northwind");
      dataSource.setServerName ("localhost");
      dataSource.setUser ("sa");
      dataSource.setPassword (System.getProperty("saPassword"));
      dataSource.setLogWriter (new PrintWriter(System.out));
   */

   return dataSource; }

public static void main (String[] argsthrows Exception {
   System.out.println ("Program started.");
   ConnectionPoolDataSource dataSource = createDataSource();
   poolMgr = new MiniConnectionPoolManager(dataSource,maxConnections);
   initDb();
   startWorkerThreads();
   pause (processingTime*1000000);
   System.out.println ("\nStopping threads.");
   stopWorkerThreads();
   System.out.println ("\nAll threads stopped.");
   poolMgr.dispose();
   System.out.println ("Program completed.")}

private static void startWorkerThreads() {
   threads = new WorkerThread[noOfThreads];
   for (int threadNo=0; threadNo<noOfThreads; threadNo++) {
      WorkerThread thread = new WorkerThread();
      threads[threadNo= thread;
      thread.threadNo = threadNo;
      thread.start()}}

private static void stopWorkerThreads() throws Exception {
   setShutdownFlag();
   for (int threadNo=0; threadNo<noOfThreads; threadNo++) {
      threads[threadNo].join()}}

private static void setShutdownFlag() {
   synchronized (shutdownObj) {
      shutdownFlag = true;
      shutdownObj.notifyAll()}}

private static void threadMain (int threadNo) {
   try {
      threadMain2 (threadNo)}
    catch (Throwable e) {
      System.out.println ("\nException in thread "+threadNo+": "+e);
      e.printStackTrace (System.out);
      setShutdownFlag()}}

private static void threadMain2 (int threadNothrows Exception {
   // System.out.println ("Thread "+threadNo+" started.");
   while (true) {
      if (!pauseRandom(threadPauseTime1)) return;
      threadTask (threadNo)}}

private static void threadTask (int threadNothrows Exception {
   Connection conn = null;
   try {
      conn = poolMgr.getConnection();
      if (shutdownFlagreturn;
      System.out.print (threadNo+" ");
      incrementThreadCounter (conn,threadNo);
      pauseRandom (threadPauseTime2)}
    finally {
      if (conn != nullconn.close()}}

private static boolean pauseRandom (int maxPauseTimethrows Exception {
   return pause (random.nextInt(maxPauseTime))}

private static boolean pause (int pauseTimethrows Exception {
   synchronized (shutdownObj) {
      if (shutdownFlagreturn false;
      if (pauseTime <= 0return true;
      int ms = pauseTime / 1000;
      int ns = (pauseTime % 10001000;
      shutdownObj.wait (ms,ns)}
   return true}

private static void initDb() throws SQLException {
   Connection conn = null;
   try {
      conn = poolMgr.getConnection();
      System.out.println ("initDb connected");
      initDb2 (conn)}
    finally {
      if (conn != nullconn.close()}
   System.out.println ("initDb done")}

private static void initDb2 (Connection connthrows SQLException {
   execSqlNoErr (conn,"drop table temp");
   execSql (conn,"create table temp (threadNo integer, ctr integer)");
   for (int i=0; i<noOfThreads; i++)
      execSql (conn,"insert into temp values("+i+",0)")}

private static void incrementThreadCounter (Connection conn, int threadNothrows SQLException {
   execSql (conn,"update temp set ctr = ctr + 1 where threadNo="+threadNo)}

private static void execSqlNoErr (Connection conn, String sql) {
   try {
      execSql (conn,sql)}
     catch (SQLException e) {}}

private static void execSql (Connection conn, String sqlthrows SQLException {
   Statement st = null;
   try {
      st = conn.createStatement();
      st.executeUpdate(sql)}
    finally {
      if (st != nullst.close()}}

// end class TestMiniConnectionPoolManager


// Copyright 2007 Christian d'Heureuse, www.source-code.biz
//
// This module is free software: you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version. See http://www.gnu.org/licenses/lgpl.html.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

package biz.source_code.miniConnectionPoolManager;

import java.util.concurrent.Semaphore;
import java.util.Stack;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.concurrent.TimeUnit;
import javax.sql.ConnectionPoolDataSource;
import javax.sql.ConnectionEvent;
import javax.sql.ConnectionEventListener;
import javax.sql.PooledConnection;

/**
* A simple standalone JDBC connection pool manager.
* <p>
* The public methods of this class are thread-safe.
* <p>
* Author: Christian d'Heureuse (<a href="http://www.source-code.biz">www.source-code.biz</a>)<br>
* License: <a href="http://www.gnu.org/licenses/lgpl.html">LGPL</a>
* <p>
* 2007-06-21: Constructor with a timeout parameter added.
*/
public class MiniConnectionPoolManager {

private ConnectionPoolDataSource       dataSource;
private int                            maxConnections;
private int                            timeout;
private PrintWriter                    logWriter;
private Semaphore                      semaphore;
private Stack<PooledConnection>        recycledConnections;
private int                            activeConnections;
private PoolConnectionEventListener    poolConnectionEventListener;
private boolean                        isDisposed;

/**
* Thrown in {@link #getConnection()} when no free connection becomes available within <code>timeout</code> seconds.
*/
public static class TimeoutException extends RuntimeException {
   private static final long serialVersionUID = 1;
   public TimeoutException () {
      super ("Timeout while waiting for a free database connection.")}}

/**
* Constructs a MiniConnectionPoolManager object with a timeout of 60 seconds.
@param dataSource      the data source for the connections.
@param maxConnections  the maximum number of connections.
*/
public MiniConnectionPoolManager (ConnectionPoolDataSource dataSource, int maxConnections) {
   this (dataSource, maxConnections, 60)}

/**
* Constructs a MiniConnectionPoolManager object.
@param dataSource      the data source for the connections.
@param maxConnections  the maximum number of connections.
@param timeout         the maximum time in seconds to wait for a free connection.
*/
public MiniConnectionPoolManager (ConnectionPoolDataSource dataSource, int maxConnections, int timeout) {
   this.dataSource = dataSource;
   this.maxConnections = maxConnections;
   this.timeout = timeout;
   try {
      logWriter = dataSource.getLogWriter()}
    catch (SQLException e) {}
   if (maxConnections < 1throw new IllegalArgumentException("Invalid maxConnections value.");
   semaphore = new Semaphore(maxConnections,true);
   recycledConnections = new Stack<PooledConnection>();
   poolConnectionEventListener = new PoolConnectionEventListener()}

/**
* Closes all unused pooled connections.
*/
public synchronized void dispose() throws SQLException {
   if (isDisposedreturn;
   isDisposed = true;
   SQLException e = null;
   while (!recycledConnections.isEmpty()) {
      PooledConnection pconn = recycledConnections.pop();
      try {
         pconn.close()}
       catch (SQLException e2) {
          if (e == nulle = e2; }}
   if (e != nullthrow e; }

/**
* Retrieves a connection from the connection pool.
* If <code>maxConnections</code> connections are already in use, the method
* waits until a connection becomes available or <code>timeout</code> seconds elapsed.
* When the application is finished using the connection, it must close it
* in order to return it to the pool.
@return a new Connection object.
@throws TimeoutException when no connection becomes available within <code>timeout</code> seconds.
*/
public Connection getConnection() throws SQLException {
   // This routine is unsynchronized, because semaphore.tryAcquire() may block.
   synchronized (this) {
      if (isDisposedthrow new IllegalStateException("Connection pool has been disposed.")}
   try {
      if (!semaphore.tryAcquire(timeout,TimeUnit.SECONDS))
         throw new TimeoutException()}
    catch (InterruptedException e) {
      throw new RuntimeException("Interrupted while waiting for a database connection.",e)}
   boolean ok = false;
   try {
      Connection conn = getConnection2();
      ok = true;
      return conn; }
    finally {
      if (!oksemaphore.release()}}

private synchronized Connection getConnection2() throws SQLException {
   if (isDisposedthrow new IllegalStateException("Connection pool has been disposed.");   // test again with lock
   PooledConnection pconn;
   if (!recycledConnections.empty()) {
      pconn = recycledConnections.pop()}
    else {
      pconn = dataSource.getPooledConnection()}
   Connection conn = pconn.getConnection();
   activeConnections++;
   pconn.addConnectionEventListener (poolConnectionEventListener);
   assertInnerState();
   return conn; }

private synchronized void recycleConnection (PooledConnection pconn) {
   if (isDisposed) { disposeConnection (pconn)return}
   if (activeConnections <= 0throw new AssertionError();
   activeConnections--;
   semaphore.release();
   recycledConnections.push (pconn);
   assertInnerState()}

private synchronized void disposeConnection (PooledConnection pconn) {
   if (activeConnections <= 0throw new AssertionError();
   activeConnections--;
   semaphore.release();
   closeConnectionNoEx (pconn);
   assertInnerState()}

private void closeConnectionNoEx (PooledConnection pconn) {
   try {
      pconn.close()}
    catch (SQLException e) {
      log ("Error while closing database connection: "+e.toString())}}

private void log (String msg) {
   String s = "MiniConnectionPoolManager: "+msg;
   try {
      if (logWriter == null)
         System.err.println (s);
       else
         logWriter.println (s)}
    catch (Exception e) {}}

private void assertInnerState() {
   if (activeConnections < 0throw new AssertionError();
   if (activeConnections+recycledConnections.size() > maxConnectionsthrow new AssertionError();
   if (activeConnections+semaphore.availablePermits() > maxConnectionsthrow new AssertionError()}

private class PoolConnectionEventListener implements ConnectionEventListener {
   public void connectionClosed (ConnectionEvent event) {
      PooledConnection pconn = (PooledConnection)event.getSource();
      pconn.removeConnectionEventListener (this);
      recycleConnection (pconn)}
   public void connectionErrorOccurred (ConnectionEvent event) {
      PooledConnection pconn = (PooledConnection)event.getSource();
      pconn.removeConnectionEventListener (this);
      disposeConnection (pconn)}}

/**
* Returns the number of active (open) connections of this pool.
* This is the number of <code>Connection</code> objects that have been
* issued by {@link #getConnection()} for which <code>Connection.close()</code>
* has not yet been called.
@return the number of active connections.
**/
public synchronized int getActiveConnections() {
   return activeConnections; }

// end class MiniConnectionPoolManager
           
         
    
  
Related examples in the same category
1. Pooled Connection Example
2. A common intermediate format for a non-XA JDBC pool
3. Your own connection pool
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.