日期:2014-05-16 浏览次数:20654 次
public class ConnectionPool {
private static Logger logger = Logger.getLogger(ConnectionPool.class);
//当前已用连接数
private static volatile int curConnections = 0;
private static Config config = null;
//初始化成功标志
private static boolean initFlag = false;
private static volatile Stack<Connection> conns;
static {
PropertyReader pr = null;
try {
pr = new PropertyReader("pool-config.properties");
config = new Config();
//设置数据库驱动
config.setDriver(pr.getValue("driver"));
//url
config.setUrl(pr.getValue("url"));
//uername
config.setUsername(pr.getValue("username"));
//password
config.setPassword(pr.getValue("password"));
//最大连接数
if(pr.getValue("maxConnections") != null){
config.setMaxConnections(Integer.valueOf(pr.getValue("maxConnections")));
}
//初始化时最小连接数
if(pr.getValue("minConnections") != null){
config.setMinConnections(Integer.valueOf(pr.getValue("minConnections")));
}
//返还连接时是否提交
if(pr.getValue("autoCommitOnClose") != null){
config.setAutoCommitOnClose(Boolean.valueOf(pr.getValue("autoCommitOnClose")));
}
//当连接池用完时客户端调用getConn()后等待获取新连接的时间
//Default: (100毫秒)
if(pr.getValue("checkoutTimeout") != null){
config.setCheckoutTimeout(Integer.valueOf(pr.getValue("checkoutTimeout")));
}
//当没有可用链接时,尝试获取链接的次数
if(pr.getValue("checkTimes") != null){
config.setCheckTimes(Integer.valueOf(pr.getValue("checkTimes")));
}
initPool();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 隐藏构造函数
*/
private ConnectionPool(){
}
/**
* 初始化连接池 保存minConnections个链接
* @throws SQLException
* @throws ClassNotFoundException
*/
private static synchronized void initPool() throws SQLException, ClassNotFoundException{
conns = new Stack<Connection>();
Class.forName(config.getDriver());
for(int i = 0 ; i < config.getMinConnections() ; i++){
Connection conn = newConnection();
conns.push(conn);
}
initFlag = true;
}
/**
* 获取一个可用链接
* @return
* @throws SQLException
* @throws InterruptedException
* @throws DBPoolException
* @throws Exception
*/
public static Connection getConn() throws SQLException, InterruptedException, DBPoolException {
Connection conn = null;
if (initFlag) {
synchronized (conns) {
// 循环次数
int times = 0;
while (null == conn && times < config.getCheckTimes() + 1) {
times++;
// 如果未达到最大链接
if (curConnections < config.getMaxConnections()) {
// 栈中未空
if (!conns.isEmpty()) {
conn = conns.pop();
// 如果返回的链接不可用
if (null == conn || conn.isClosed()) {
conn = newConnection();
}
// 栈中空了
} else {
conn = newConnection();
}
} else {
conns.wait(config.getCheckoutTimeout());
}
}
if(null == conn){
logger.warn("获取链接超时!!!!!");
throw new DBPoolException("获取链接超时!!!!!");
}else{
curConnections++;
conns.notifyAll();
}
}
} else {
logger.error("连接池初始化失败!!!!");
throw new DBPoolException("连接池初始化失败!!!!");
}
return conn;
}
/**
* 归还一个链接
* @param conn
* @throws SQLException
* @throws InterruptedException
*/
public static void returnConn(Connection conn) throws SQLException, InterruptedException {
synchronized (conns) {
if (null != conn && !conn.isClosed()) {
// 如果设置归还前自动提交为真
if (config.isAutoCommitOnClose()) {
conn.commit();
} else {
conn.rollback();
}
}
int times = 0;
//尝试归还5次 如果归还失败则关闭连接
while (times < 6) {
t