📄 dbpool.java
字号:
/*------------------------------------------------------------------------------Name: DbPool.javaProject: org.xmlBlasterProject: xmlBlaster.orgCopyright: xmlBlaster.org, see xmlBlaster-LICENSE file------------------------------------------------------------------------------*/package org.xmlBlaster.contrib.db;import java.util.logging.Logger;import java.util.logging.Level;import java.io.BufferedReader;import java.io.FileReader;import java.sql.Connection;import java.sql.Statement;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.DriverManager;import java.util.HashSet;import java.util.Set;import java.util.StringTokenizer;import org.xmlBlaster.contrib.I_Info;import org.xmlBlaster.contrib.PropertiesInfo;import org.xmlBlaster.util.pool.PoolManager;import org.xmlBlaster.util.pool.I_PoolManager;import org.xmlBlaster.util.pool.ResourceWrapper;import org.xmlBlaster.util.Global;import org.xmlBlaster.util.ThreadLister;import org.xmlBlaster.util.XmlBlasterException;import org.xmlBlaster.util.def.ErrorCode;/** * Simple implementation of the database JDBC connection pool. * <p> * Following configuration paramaters are available: * <pre> * db.url=jdbc:oracle:thin:@localhost:1521:orcl * db.user=system * db.password=manager * db.maxInstances=10 * db.busyToIdleTimeout=0 // How long may a query last [millis] * db.idleToEraseTimeout=10*60*1000L // How long does an unused connection survive (10 min) * db.maxResourceExhaustRetries=5 * db.resourceExhaustSleepGap=1000 // [millis] * </pre> * @author Marcel Ruff */public class DbPool implements I_DbPool, I_PoolManager { private static Logger log = Logger.getLogger(DbPool.class.getName()); private I_Info info; private PoolManager poolManager; private String dbUrl; private String dbUser; private String dbPasswd; /** If the pool is exhausted, we poll the given times */ private int maxResourceExhaustRetries; /** If the pool is exhausted, we poll every given millis<br /> Please note that the current request thread will block for maxResourceExhaustRetries*resourceExhaustSleepGap millis. */ private long resourceExhaustSleepGap; private final Object meetingPoint = new Object(); private int initCount = 0; /** * Default constructor, you need to call <tt>init(info)</tt> thereafter. */ public DbPool() { // void } /** * @see org.xmlBlaster.contrib.I_ContribPlugin#getUsedPropertyKeys() */ public Set getUsedPropertyKeys() { Set set = new HashSet(); set.add("db.url"); set.add("db.user"); set.add("db.password"); set.add("db.maxInstances"); set.add("db.busyToIdleTimeout"); set.add("db.idleToEraseTimeout"); set.add("db.maxResourceExhaustRetries"); set.add("db.resourceExhaustSleepGap"); return set; } /** * @see org.xmlBlaster.contrib.dbwatcher.db.I_DbPool#init(I_Info) */ public synchronized void init(I_Info info) { if (this.initCount > 0) { this.initCount++; return; } this.info = info; this.dbUrl = this.info.get("db.url", ""); this.dbUser = this.info.get("db.user", ""); this.dbPasswd = this.info.get("db.password", ""); int maxInstances = this.info.getInt("db.maxInstances", 10); // How long may a query last long busyToIdle = this.info.getLong("db.busyToIdleTimeout", 0); // How long does an unused connection survive (10 min) long idleToErase = this.info.getLong("db.idleToEraseTimeout", 120*60*1000L); this.maxResourceExhaustRetries = this.info.getInt("db.maxResourceExhaustRetries", 5); // millis this.resourceExhaustSleepGap = this.info.getLong("db.resourceExhaustSleepGap", 1000); initDrivers(); this.poolManager = new PoolManager("DbPool", this, maxInstances, busyToIdle, idleToErase); this.initCount++; } public String getUser() { return this.dbUser; } /** * Load the JDBC drivers given in environment. * <p /> * Default is JdbcDriver.drivers=sun.jdbc.odbc.JdbcOdbcDriver */ private void initDrivers() { String drivers = this.info.get("jdbc.drivers", "oracle.jdbc.driver.OracleDriver"); StringTokenizer st = new StringTokenizer(drivers, ":"); int numDrivers = st.countTokens(); String driver = ""; for (int i = 0; i < numDrivers; i++) { try { driver = st.nextToken().trim(); //log.info("Trying JDBC driver Class.forName('" + driver + "') ..."); Class cl = Class.forName(driver); java.sql.Driver dr = (java.sql.Driver)cl.newInstance(); java.sql.DriverManager.registerDriver(dr); log.info("Jdbc driver '" + driver + "' loaded."); } catch (Throwable e) { log.warning("Couldn't initialize driver <" + driver + ">, please check your CLASSPATH"); } } if (numDrivers == 0) { log.warning("No JDBC drivers given, set 'jdbc.drivers' to point to your DB drivers if wanted, e.g. jdbc.drivers=oracle.jdbc.driver.OracleDriver:org.gjt.mm.mysql.Driver:postgresql.Driver"); } } /** * @see org.xmlBlaster.contrib.dbwatcher.db.I_DbPool#reserve() * @throws Exception of type XmlBlasterException or IllegalArgumentException */ public Connection reserve() throws Exception { if (this.poolManager == null) throw new IllegalArgumentException("PoolManager is not initialized"); int ii=0; while (true) { try { synchronized(this.meetingPoint) { ResourceWrapper rw = this.poolManager.reserve(PoolManager.USE_OBJECT_REF); Connection con = (Connection)rw.getResource(); return con; } } catch (XmlBlasterException e) { if (e.getErrorCode() == ErrorCode.RESOURCE_EXHAUST && ii < this.maxResourceExhaustRetries) { if (ii == 0) log.warning("Caught exception in reserve(), going to poll " + this.maxResourceExhaustRetries + " times every " + resourceExhaustSleepGap + " millis"); try { Thread.sleep(this.resourceExhaustSleepGap); } catch (InterruptedException ie) { /* Ignore */ } ii++; } else { log.warning("Other stacks are doing: " + ThreadLister.getAllStackTraces()); throw e; } } } // while } /** * @see org.xmlBlaster.contrib.dbwatcher.db.I_DbPool#release(java.sql.Connection) * @throws Exception of type XmlBlasterException or IllegalArgumentException */ public void release(Connection con) throws Exception { if (this.poolManager == null) throw new IllegalArgumentException("PoolManager is not initialized"); synchronized(this.meetingPoint) { this.poolManager.release(""+con); } } /** * @see org.xmlBlaster.contrib.dbwatcher.db.I_DbPool#erase(java.sql.Connection) * @throws IllegalArgumentException */ public void erase(Connection con) throws IllegalArgumentException { if (this.poolManager == null) throw new IllegalArgumentException("PoolManager is not initialized"); synchronized(this.meetingPoint) { this.poolManager.erase(""+con); log.fine("connections: busy='" + this.poolManager.getNumBusy() + "',idle=' " + this.poolManager.getNumIdle() + "' (after erase)"); } } /** * Cleanup and destroy everything. */ private void destroy() { synchronized(this.meetingPoint) { if (this.poolManager != null) { if (log.isLoggable(Level.FINE)) log.fine("Destroying pool: " + this.poolManager.toXml()); this.poolManager.destroy(); this.poolManager = null; } } } /** * This callback does nothing (enforced by interface I_PoolManager) * @param resource The Connection object * @see org.xmlBlaster.util.pool.I_PoolManager#idleToBusy(Object) */ public void idleToBusy(Object resource) { // Connection con = (Connection)resource; } /** * This callback does nothing (enforced by interface I_PoolManager * @param resource The Connection object * @see org.xmlBlaster.util.pool.I_PoolManager#busyToIdle(Object) */ public void busyToIdle(Object resource) { // Connection con = (Connection)resource; } /**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -