All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.bixuebihui.sql.ConnectionPool Maven / Gradle / Ivy

Go to download

a fast small database connection pool and a active record flavor mini framework

There is a newer version: 1.15.3.3
Show newest version
// Decompiled by DJ v2.9.9.60 Copyright 2000 Atanas Neshkov  Date: 2005-1-4 11:28:19
// Home Page : http://members.fortunecity.com/neshkov/dj.html  - Check often for new version!
// Decompiler options: packimports(3)
// Source File Name:   ConnectionPool.java

package com.bixuebihui.sql;

import com.bixuebihui.util.JavaAlarm;
import com.bixuebihui.util.TimeoutException;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.Executor;

/**
 * 

ConnectionPool class.

* * @author xingwx * @version $Id: $Id */ public class ConnectionPool { private static final int MIN_TIMEOUT_MILLI_SECONDS = 50; private static final int CONNECTION_TIMEOUT = 100; private static final Logger LOG = LoggerFactory.getLogger(ConnectionPool.class); /** * Constant CONNECTION_POOL="ConnectionPool: " */ public static final String CONNECTION_POOL = "ConnectionPool: "; Executor executor = Runnable::run; private final int maxPrepStmts; /** *

Setter for the field cacheStatements.

* * @param cacheStatements a boolean. */ public void setCacheStatements(boolean cacheStatements) { this.cacheStatements = cacheStatements; } /** *

isCacheStatements.

* * @return a boolean. */ public boolean isCacheStatements() { return cacheStatements; } /** *

setTracing.

* * @param flag a boolean. */ public synchronized void setTracing(boolean flag) { trace = flag; } /** *

Getter for the field alias.

* * @return a {@link java.lang.String} object. */ public String getAlias() { return alias; } /** *

Getter for the field numRequests.

* * @return a int. */ public int getNumRequests() { return numRequests; } /** *

Getter for the field numWaits.

* * @return a int. */ public int getNumWaits() { return numWaits; } /** *

getNumCheckoutTimeouts.

* * @return a int. */ public int getNumCheckoutTimeouts() { return numCheckoutTimeout; } /** *

Getter for the field maxConn.

* * @return a int. */ public int getMaxConn() { return maxConn; } /** *

size.

* * @return a int. */ public int size() { return connVector.size(); } /** *

Constructor for ConnectionPool.

* * @param alias a {@link java.lang.String} object. * @param url a {@link java.lang.String} object. * @param username a {@link java.lang.String} object. * @param password a {@link java.lang.String} object. * @param maxConn a int. * @param timeoutMilliSeconds a int. * @param checkoutMilliSeconds a int. * @param maxCheckout a int. * @param maxPrepStmts a int. */ public ConnectionPool(String alias, String url, String username, String password, int maxConn, int timeoutMilliSeconds, int checkoutMilliSeconds, int maxCheckout, int maxPrepStmts) { numConnectionFaults = 0; prefetchSize = -1; this.timeoutMilliSeconds = timeoutMilliSeconds; if (this.timeoutMilliSeconds < CONNECTION_TIMEOUT) { this.timeoutMilliSeconds = CONNECTION_TIMEOUT; } this.checkoutMilliSeconds = checkoutMilliSeconds; this.alias = alias; this.url = url; this.username = username; this.password = password; this.maxConn = maxConn; this.maxCheckout = maxCheckout; numRequests = 0; numWaits = 0; numCheckoutTimeout = 0; connVector = new ArrayList<>(maxConn); trace = false; cacheStatements = true; this.maxPrepStmts = maxPrepStmts; } private void debug(Exception e) { if (trace) { LOG.debug("exception",e); } } private void warn(String warning) { LOG.warn(CONNECTION_POOL + alias + " " + warning); } private void error(String errormsg) { LOG.error(CONNECTION_POOL + alias + " " + errormsg); } /** *

reapIdleConnections.

*/ public synchronized void reapIdleConnections() { debug(" reapIdleConnections() starting, size=" + size()); long currentTimeInMillis = System.currentTimeMillis(); long keepToTime = currentTimeInMillis - timeoutMilliSeconds; //空保持时间 long checkoutTime = currentTimeInMillis - checkoutMilliSeconds; //单次租用期限 for (int i = 0; i < connVector.size(); ) { PooledConnection pooledconnection = connVector.get(i); if (pooledconnection.isLocked() && pooledconnection.getLastAccess() < checkoutTime) { numCheckoutTimeout++; warn(" Warning: found timed-out connection\n" + " (链接获取时间LastAccess=" + pooledconnection.getLastAccess() + " 超出最大租用时间=" + checkoutMilliSeconds + " )\n" + pooledconnection.dumpInfo()); removeConnection(pooledconnection); notifyAll(); } else if (pooledconnection.getLastAccess() < keepToTime) { if (pooledconnection.getLock()) { removeConnection(pooledconnection); pooledconnection.releaseLock(); notifyAll(); } else if (timeoutMilliSeconds > MIN_TIMEOUT_MILLI_SECONDS) { error("force stop connection = " + pooledconnection); LOG.error(pooledconnection.dumpInfo()); try { pooledconnection.abort(executor); } catch (SQLException e) { LOG.warn("abort", e); } removeConnection(pooledconnection); pooledconnection.releaseLock(); notifyAll(); } else { error("find timeout connection = " + pooledconnection + ", but timeoutMilliSeconds is too small or net set :" + timeoutMilliSeconds); } } else { i++; } } debug(" reapIdleConnections() finished"); } private void debug(String msg) { if (trace) { LOG.debug(CONNECTION_POOL + alias + " " + msg); } } private void removeConnection(PooledConnection pooledconnection) { try { connVector.remove(pooledconnection); new JavaAlarm(pooledconnection, timeoutMilliSeconds); } catch (TimeoutException e1) { debug(e1); //try to abort try { warn("force close timeout connection " + pooledconnection + " timeout=" + timeoutMilliSeconds); pooledconnection.abort(executor); pooledconnection.closeStatements(); pooledconnection.close(); connVector.remove(pooledconnection); } catch (SQLException e) { LOG.warn("force close", e); } } } /** *

removeAllConnections.

*/ public synchronized void removeAllConnections() { debug(" removeAllConnections() called"); PooledConnection pooledconnection; for (; !connVector.isEmpty(); removeConnection(pooledconnection)) { pooledconnection = connVector.get(0); } } private synchronized Connection releaseConnection(PooledConnection pooledconnection) { if (trace) { pooledconnection.setTraceException(ExceptionUtils.getStackTrace(new Throwable())); } return pooledconnection; } /** * Set the setNetworkTimeout little bit longer than my own SQL execution timeout * * @return timeoutMilliSeconds*15/10 */ private int getNetworkTimeout() { return timeoutMilliSeconds * 15 / 10; } /** *

getConnection.

* * @return a {@link java.sql.Connection} object. * @throws java.sql.SQLException if any. */ public synchronized Connection getConnection() throws SQLException { debug(" getConnection() called"); numRequests++; do { do { for (int i = 0; i < connVector.size(); i++) { PooledConnection pooledconnection = connVector.get(i); if (pooledconnection.getLock()) { return releaseConnection(pooledconnection); } } debug(" all connections locked. calling" + " createConnection()"); if (connVector.size() < maxConn) { debug(" opening new connection to database size=" + size()); Connection connection = createDriverConnection(); debug(" finished opening new connection"); PooledConnection pooledconnection1 = new PooledConnection(connection, this, maxPrepStmts); pooledconnection1.getLock(); if (timeoutMilliSeconds > MIN_TIMEOUT_MILLI_SECONDS) { try { pooledconnection1.setNetworkTimeout(executor, getNetworkTimeout()); debug("create connection with timeoutMiliSeconds = " + timeoutMilliSeconds); } catch (SQLException e) { if (trace) { LOG.warn("network timeout", e); } break; } } else { debug(" timeoutMiliSeconds = " + timeoutMilliSeconds + ", which is too small to set "); } connVector.add(pooledconnection1); return releaseConnection(pooledconnection1); } try { debug(" pool is full. calling wait()"); numWaits++; wait(); } catch (InterruptedException interruptedexception) { debug("Get Connection interrupted"); Thread.currentThread().interrupt(); } } while (!trace); debug(" awoken from wait(). trying to grab an available connection"); } while (true); } /** *

returnConnection.

* * @param pooledconnection a {@link PooledConnection} object. */ public synchronized void returnConnection(PooledConnection pooledconnection) { if (maxCheckout > 0 && pooledconnection.getCheckoutCount() >= maxCheckout) { debug(" connection checked out max #" + maxCheckout + " of times." + " closing it."); removeConnection(pooledconnection); } debug(" releasing lock and calling notifyAll()"); pooledconnection.releaseLock(); notifyAll(); } Connection createDriverConnection() throws SQLException { Connection cn = DriverManager.getConnection(url, username, password); if (timeoutMilliSeconds > MIN_TIMEOUT_MILLI_SECONDS) { try { cn.setNetworkTimeout(executor, getNetworkTimeout()); } catch (Exception e) { if (trace) { LOG.warn("timeout", e); } } } return cn; } /** *

toString.

* * @return a {@link java.lang.String} object. */ @Override public String toString() { return "{ url:'" + url + "', username:'" + username + "', password:'" + StringUtils.abbreviate(password, 4) + "'}"; } /** *

Setter for the field prefetchSize.

* * @param prefetchSize a int. */ public void setPrefetchSize(int prefetchSize) { this.prefetchSize = prefetchSize; } /** *

Getter for the field prefetchSize.

* * @return a int. */ public int getPrefetchSize() { return prefetchSize; } /** *

Constructor for ConnectionPool.

* * @param alias a {@link java.lang.String} object. * @param url a {@link java.lang.String} object. * @param username a {@link java.lang.String} object. * @param password a {@link java.lang.String} object. * @param maxConn a int. * @param timeoutMilliSeconds a int. * @param checkoutMilliSeconds a int. * @param maxCheckout a int. */ public ConnectionPool(String alias, String url, String username, String password, int maxConn, int timeoutMilliSeconds, int checkoutMilliSeconds, int maxCheckout) { this(alias, url, username, password, maxConn, timeoutMilliSeconds, checkoutMilliSeconds, maxCheckout, 200); } /** *

dumpInfo.

* * @return a {@link java.lang.String} object. */ public String dumpInfo() { String s = System.getProperty("line.separator"); String s1 = "Pool: " + this + s; s1 += "\tAlias: " + getAlias() + s; s1 += "\tMax connections: " + getMaxConn() + s; s1 += "\tCheckouts: " + getNumRequests() + s; s1 += "\tThread waits: " + getNumWaits() + s; s1 += "\tConnections found closed: " + numConnectionFaults + s; s1 += "\tConnections reaped by timeout: " + getNumCheckoutTimeouts() + s; s1 += "\tConnections currently in pool: " + size() + s; StringBuilder sb = new StringBuilder(s1); synchronized (connVector) { for (PooledConnection pooledConnection : connVector) { if (pooledConnection != null) { sb.append(pooledConnection.dumpInfo()); } } } return sb.toString(); } List connVector; String url; private final String username; private final String password; private final String alias; private final int maxConn; private int timeoutMilliSeconds; private final int checkoutMilliSeconds; private int numCheckoutTimeout; private int numRequests; private int numWaits; private final int maxCheckout; private boolean cacheStatements; int numConnectionFaults; private boolean trace; private int prefetchSize; }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy