//文件:dbconnectiondefaultpool.java的第一部分
//请注意看里面注明的一处需要修改连接参数的地方
package com.qingtuo.db.pool;
import java.sql.*;
import java.util.*;
import java.io.*;
import java.text.*;
import java.util.date;
/**
* default jive connection provider. it uses the excellent connection pool
* available from http://www.javaexchange.com. this connection provider is a
* a good choice unless you can use a container-managed one.
*/
public class dbconnectiondefaultpool extends dbconnectionprovider {
private static final string name = "default connection pool";
private static final string description = "the default connection provider "
+ "that uses the connection pool from javaexchange.com. it works with "
+ "almost any database setup, is customizable, and offers good performance. "
+ "use this connection provider unless you have your own or can use a "
+ "container managed connection pool.";
private static final string author = "coolservlets.com";
private static final int major_version = 1;
private static final int minor_version = 0;
private static final boolean pooled = true;
private connectionpool connectionpool = null;
private properties props;
private properties propdescriptions;
private object initlock = new object();
public dbconnectiondefaultpool() {
//this.manager = manager;
props = new properties();
propdescriptions = new properties();
//initialize all property values
initializeproperties();
//load any existing property values
loadproperties();
}
/**
* returns a database connection.
*/
public connection getconnection() {
if (connectionpool == null) {
//block until the init has been done
synchronized(initlock) {
//if still null, something has gone wrong
if (connectionpool == null) {
system.err.println("warning: dbconnectiondefaultpool.getconnection() was " +
"called when the internal pool has not been initialized.");
return null;
}
}
}
return new connectionwrapper(connectionpool.getconnection(), connectionpool);
}
/**
* starts the pool.
*/
protected void start() {
//acquire lock so that no connections can be returned.
synchronized (initlock) {
//get properties
string driver = props.getproperty("driver");
string server = props.getproperty("server");
string username = props.getproperty("username");
string password = props.getproperty("password");
int minconnections = 0, maxconnections = 0;
double connectiontimeout = 0.0;
try {
minconnections = integer.parseint(props.getproperty("minconnections"));
maxconnections = integer.parseint(props.getproperty("maxconnections"));
connectiontimeout = double.parsedouble(props.getproperty("connectiontimeout"));
}
catch (exception e) {
system.err.println("error: could not parse default pool properties. " +
"make sure the values exist and are correct.");
e.printstacktrace();
return;
}
string logpath = props.getproperty("logpath");
try {
connectionpool = new connectionpool(driver, server, username, password,
minconnections, maxconnections, logpath, connectiontimeout);
}
catch (ioexception ioe) {
system.err.println("error starting dbconnectiondefaultpool: " + ioe);
ioe.printstacktrace();
}
}
}
/**
* restarts the pool to take into account any property changes.
*/
protected void restart() {
//kill off pool.
destroy();
//reload properties.
loadproperties();
//start a new pool.
start();
}
/**
* destroys the connection pool.
*/
protected void destroy() {
if (connectionpool != null) {
try {
connectionpool.destroy(1);
}
catch (exception e) {
e.printstacktrace();
}
}
//release reference to connectionpool
connectionpool = null;
}
/**
* returns the value of a property of the connection provider.
*
* @param name the name of the property.
* @returns the value of the property.
*/
public string getproperty(string name) {
return (string)props.get(name);
}
/**
* returns the description of a property of the connection provider.
*
* @param name the name of the property.
* @return the description of the property.
*/
public string getpropertydescription(string name) {
return (string)propdescriptions.get(name);
}
/**
* returns an enumeration of the property names for the connection provider.
*/
public enumeration propertynames() {
return props.propertynames();
}
/**
* sets a property of the connection provider. each provider has a set number
* of properties that are determined by the author. trying to set a non-
* existant property will result in an illegalargumentexception.
*
* @param name the name of the property to set.
* @param value the new value for the property.
*
*/
public void setproperty(string name, string value) {
props.put(name, value);
saveproperties();
}
/**
* give default values to all the properties and descriptions.
*/
private void initializeproperties() {
props.put("driver","");
props.put("server","");
props.put("username","");
props.put("password","");
props.put("minconnections","");
props.put("maxconnections","");
props.put("logpath","");
props.put("connectiontimeout","");
propdescriptions.put("driver","jdbc driver. e.g. oracle.jdbc.driver.oracledriver");
propdescriptions.put("server","jdbc connect string. e.g. jdbc:oracle:thin:@203.92.21.109:1526:orcl");
propdescriptions.put("username","database username. e.g. scott");
propdescriptions.put("password","database password. e.g. tiger");
propdescriptions.put("minconnections","minimum # of connections to start with in pool. three is the recommended minimum");
propdescriptions.put("maxconnections","maximum # of connections in dynamic pool. fifteen should give good performance for an average load.");
propdescriptions.put("logpath","absolute path name for log file. e.g. c:\\logs\\jivedblog.log");
propdescriptions.put("connectiontimeout","time in days between connection resets. e.g. .5");
}
/**
* load whatever properties that already exist.
*/
private void loadproperties() {
//在这里修改一些连接参数
//in 2000
/*
string driver="org.gjt.mm.mysql.driver";
string server="jdbc:mysql://192.100.100.11/pcc";
string username="pcc";
string password="pcc123";
string minconnections="3";
string maxconnections="10";
string logpath="c:\\temp\\qingtuodblog.log";
string connectiontimeout="0.5";
*/
//in linux
string driver="org.gjt.mm.mysql.driver";
string server="jdbc:mysql://192.100.100.1/qingtuo";
//string server="jdbc:mysql://192.168.0.1/qingtuo";
string username="qingtuo";
string password="qingtuo";
string minconnections="3";
string maxconnections="20";
string logpath="c:\\temp\\qingtuodblog.log";
// string logpath="/tmp/qingtuodblog.log";
string connectiontimeout="0.5";
if (driver != null) { props.setproperty("driver", driver); }
if (server != null) { props.setproperty("server", server); }
if (username != null) { props.setproperty("username", username); }
if (password != null) { props.setproperty("password", password); }
//if (database != null) { props.setproperty("database", database); }
if (minconnections != null) { props.setproperty("minconnections", minconnections); }
if (maxconnections != null) { props.setproperty("maxconnections", maxconnections); }
if (logpath != null) { props.setproperty("logpath", logpath); }
if (connectiontimeout != null) { props.setproperty("connectiontimeout", connectiontimeout); }
}
private void saveproperties() {
propertymanager.setproperty("dbconnectiondefaultpool.driver", props.getproperty("driver"));
propertymanager.setproperty("dbconnectiondefaultpool.server", props.getproperty("server"));
propertymanager.setproperty("dbconnectiondefaultpool.username", props.getproperty("username"));
propertymanager.setproperty("dbconnectiondefaultpool.password", props.getproperty("password"));
propertymanager.setproperty("dbconnectiondefaultpool.minconnections", props.getproperty("minconnections"));
propertymanager.setproperty("dbconnectiondefaultpool.maxconnections", props.getproperty("maxconnections"));
propertymanager.setproperty("dbconnectiondefaultpool.logpath", props.getproperty("logpath"));
propertymanager.setproperty("dbconnectiondefaultpool.connectiontimeout", props.getproperty("connectiontimeout"));
}
private class connectionpool implements runnable {
private thread runner;
private connection[] connpool;
private int[] connstatus;
private long[] connlocktime, conncreatedate;
private string[] connid;
private string dbdriver, dbserver, dblogin, dbpassword, logfilestring;
private int currconnections, connlast, minconns, maxconns, maxconnmsec;
//available: set to false on destroy, checked by getconnection()
private boolean available=true;
private printwriter log;
private sqlwarning currsqlwarning;
private string pid;
/**
* creates a new connection broker<br>
* dbdriver: jdbc driver. e.g. oracle.jdbc.driver.oracledriver<br>
* dbserver: jdbc connect string. e.g. jdbc:oracle:thin:@203.92.21.109:1526:orcl<br>
* dblogin: database login name. e.g. scott<br>
* dbpassword: database password. e.g. tiger<br>
* minconns: minimum number of connections to start with.<br>
* maxconns: maximum number of connections in dynamic pool.<br>
* logfilestring: absolute path name for log file. e.g. c:\temp\mylog.log <br>
* maxconntime: time in days between connection resets. (reset does a basic cleanup)<br>
*/
public connectionpool (string dbdriver, string dbserver, string dblogin,
string dbpassword, int minconns, int maxconns,
string logfilestring, double maxconntime) throws ioexception
{
connpool = new connection[maxconns];
connstatus = new int[maxconns];
connlocktime = new long[maxconns];
conncreatedate = new long[maxconns];
connid = new string[maxconns];
currconnections = minconns;
this.maxconns = maxconns;
this.dbdriver = dbdriver;
this.dbserver = dbserver;
this.dblogin = dblogin;
this.dbpassword = dbpassword;
this.logfilestring = logfilestring;
maxconnmsec = (int)(maxconntime * 86400000.0); //86400 sec/day
if(maxconnmsec < 30000) { // recycle no less than 30 seconds.
maxconnmsec = 30000;
}
try {
log = new printwriter(new fileoutputstream(logfilestring),true);
// cant open the requested file. open the default file.
}
catch (ioexception e1) {
system.err.println("warning: dbconnectiondefaultpool could not open \""
+ logfilestring + "\" to write log to. make sure that your java " +
"process has permission to write to the file and that the directory exists."
);
try {
log = new printwriter(new fileoutputstream("dcb_" +
system.currenttimemillis() + ".log"), true
);
}
catch (ioexception e2) {
throw new ioexception("cant open any log file");
}
}
// write the pid file (used to clean up dead/broken connection)
simpledateformat formatter
= new simpledateformat ("yyyy.mm.dd g at hh:mm:ss a zzz");
java.util.date nowc = new java.util.date();
pid = formatter.format(nowc);
bufferedwriter pidout = new bufferedwriter(new
filewriter(logfilestring + "pid"));
pidout.write(pid);
pidout.close();
log.println("starting connectionpool:");
log.println("dbdriver = " + dbdriver);
log.println("dbserver = " + dbserver);
log.println("dblogin = " + dblogin);
log.println("log file = " + logfilestring);
log.println("minconnections = " + minconns);
log.println("maxconnections = " + maxconns);
log.println("total refresh interval = " + maxconntime + " days");
log.println("—————————————–");
// initialize the pool of connections with the mininum connections:
// problems creating connections may be caused during reboot when the
// servlet is started before the database is ready. handle this
// by waiting and trying again. the loop allows 5 minutes for
// db reboot.
boolean connectionssucceeded=false;
int dbloop=20;
try {
for(int i=1; i < dbloop; i++) {
try {
for(int j=0; j < currconnections; j++) {
log.println("create conn "+j);
createconn(j);
}
connectionssucceeded=true;
break;
}
catch (sqlexception e){
log.println("—>attempt (" + string.valueof(i) +
" of " + string.valueof(dbloop) +
") failed to create new connections set at startup: ");
log.println(" " + e);
log.println(" will try again in 15 seconds…");
try { thread.sleep(15000); }
catch(interruptedexception e1) {}
}
}
if(!connectionssucceeded) { // all attempts at connecting to db exhausted
log.println("\r\nall attempts at connecting to database exhausted");
throw new ioexception();
}
}
catch (exception e) {
throw new ioexception();
}
// fire up the background housekeeping thread
runner = new thread(this);
runner.start();
} //end connectionpool()
