分享自己寫的db4o 連線池

gltbeyond發表於2008-05-30
初步實現,如有問題歡迎拍磚。

package com.glt.table.db4oUtil;

import java.util.LinkedList;

import org.apache.log4j.Logger;

import com.db4o.Db4o;
import com.db4o.ObjectContainer;
import com.db4o.ObjectServer;
import com.db4o.config.Configuration;

/**
* 必須實現connection pool,因為在web應用中,servlet必定是多執行緒的。
* 1. 支援多客戶端;
* 2. 事務必須手工commit;
* 3. 一個JVM中只能同時連線一個資料庫。
* 4. 使用reset()更改引數。
*
* @author guolt
*/
public class Db4oCP {
private static final Logger log = Logger
.getLogger("com.glt.table.db4oUtil");
//資料庫檔案路徑
private static String DATAFILE = "data/tableBuying.yap";
//連線池最小保持數
private static int MIN = 5;
//連線池最大保持數
private static int MAX = 10;
// 當前已經被獲取使用的連線個數
private static int counts = 0;

//存放ObjectContainer物件
private static LinkedList connectionList=null;

private static ObjectServer objectServer = null;

// must be static 否則不會主動執行,不會在static 方法之前執行
static{
try {
init();
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* 初始化Connection Pool中的Db4o的連線
* @throws Exception
*/
private static void init() throws Exception {
try {
connectionList=new LinkedList();
if(DATAFILE==null ||MIN==MAX){
log.error("Db4oCP initi faild, Please check configuration...");
System.exit(-1);
}
objectServer = Db4o.openServer(DATAFILE, 0);
Configuration cfg=Db4o.configure();
log.info("Db4o configuration: activationDepth:"+cfg.activationDepth());
//Db4o級聯儲存設定
//The default setting is 1: Only the object passed to ObjectContainer.set(java.lang.Object) will be updated.
//In client-server environment this setting should be used on both client and server sides
Db4o.configure().updateDepth(1);
for (int i = 0; i < MIN; i++) {
// 放在末尾
connectionList.add(objectServer.openClient());
}
} catch (Exception e) {
throw new Exception("Db4o init Faild");
}
log.info("Db4oCP init OK[DataFile:"+DATAFILE + "|MIN:"+MIN +"|MAX:"+MAX+ "|Free:" + connectionList.size()+"]");
}

public synchronized static ObjectContainer getODBConnection() throws Exception {
if (connectionList == null) {
log.error("Db4oCP is null.");
}
while (connectionList.isEmpty()) {
// 如果在MIX,MAX之間仍然建立並返回;否則出錯。
if (counts < MAX) {
log.debug("DB4oCP free over MIN ,now new One CP..");
connectionList.add(objectServer.openClient());
} else {
throw new Exception("DB4oCP over MAX.");
}
}
// 移除並返回此列表的第一個元素
ObjectContainer odb = (ObjectContainer) connectionList.removeFirst();
counts++;
log.info("Db4oCP getODBConnection OK[used:" + counts + " |MAX:" + MAX + "|Free:" + connectionList.size()+"]");
return odb;
}

/**
* 釋放,回收連線。
*/
public synchronized static void release(ObjectContainer odb) {
if(odb==null){
return;
}
counts--;
connectionList.add(odb);
log.info("Db4oCP release OK[used:" + counts + "|MAX:"+MAX+"|Free:"
+ connectionList.size()+"]");
//must set null ,or else be conflict.
odb=null;
}

/**
* 關閉資料庫連線池
* @deprecated 呼叫會產生不可預料結果
* */
public static void cloesDB(){
connectionList=null;
counts=0;
objectServer.close();
}

/**
* 重置資料庫連線池
* */
public static void reset(String dataFile,int min,int max){
DATAFILE=dataFile;
MIN=min;
MAX=max;
connectionList=null;
counts=0;
objectServer.close();
try {
init();
log.info("Db4oCP reset OK[DataFile:"+DATAFILE + "|MIN:"+MIN +"|MAX:"+MAX+ "|Free:" + connectionList.size()+"]");
} catch (Exception e) {
e.printStackTrace();
}
}


}

相關文章