`
zeroliu
  • 浏览: 195779 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

重新实现的db4o连接池

阅读更多
【虎.无名】看了Roson的db4o连接池实现,似乎存在一些问题:
1,使用sleep或者wait/notify是为了避免循环忙等待,这个非常消耗CPU资源,否则不适合用于生产环境。
2,限制在Jdk1.5以上版本了,并非必要。
3,用户应该可以选择本地模式,还是远程模式;对于后者,需要远程服务器和端口,同时,在代码上,就无需Db4o.openServer了。
于是乎,一时手痒,就重新实现了一个,看看测试效果,虽然达到了互斥,但是db4o内部似乎还存在一些问题。set进去的类,没有成功保存,奇怪中。
/**  
 * Created on 2006-11-24 
 * @author liusheng (nike.lius@gmail.com)
 * @function 针对db4o的连接池管理,
 * @link file:///D:/OSS/db4o-5.5/doc/tutorial/index.html
 * DONE 参考了Rosen的ConnectionPool实现,并加以改进,Blog主页如下;
 * @link http://www.blogjava.net/rosen/category/13739.html
 * DONE 采用setter依赖注入方式,兼容Spring框架;
 * DONE 完成Poll拉模式连接池;db4o_pool中只存放空闲连接;
 * DONE 在main()中使用多线程测试,
 * TODO 在多线程中,set()后无效,已经commit了,奇怪。
*/
public class Db4oPool implements Db4oPoolInf {
	protected static Log _log = LogFactory.getLog(Db4oPool.class);
	//-------------------------------------
	private	int		_minSize = 1;	//允许的空闲连接;
	private	int 	_maxSize = 2;	
	public void setMinSize(int n) { _minSize = n; }
	public void setMaxSize(int n) { _maxSize = n; }
	public int getMinSize() 	{ return _minSize;	}
	public int getMaxSize() 	{ return _maxSize;	}
	
	private String	_file = null;
	private String	_host = null;
	private int		_port = 0;
	private String	_usr = null;
	private String	_pwd = null;
	
	public void set_file(String file) {	_file = file; }
	public void set_host(String host) {	_host = host; }
	public void set_port(int	port) {	_port = port; }
	public void set_usr(String s)	{	_usr = s; }
	public void set_pwd(String s)	{	_pwd = s; }
	//-------------------------------------
	private	ObjectServer	db4o_server = null;	//only for local
	private	List			db4o_pool = null;	//只存放空闲连接
	private	String			db4o_mode = null;
	private	int				db4o_count = 0;	//当前连接数
	//-------------------------------------
	public Db4oPool() {}		//需要调用set方法;
	public Db4oPool(String file) {
		set_file(file);		//Embedded模式
		db4o_mode = "embedded";
	}
	public Db4oPool(String host, int port, String usr, String pwd) {
		set_host(host);		//Client模式
		set_port(port);
		set_usr(usr);
		set_pwd(pwd);
		db4o_mode = "remote";
	}	
	//-------------------------------------
	public void start() throws Exception {
		synchronized(this){
			if (db4o_pool!=null)	return;
			db4o_pool = Collections.synchronizedList(new LinkedList());
			if (_file!=null) 	{	//对于embedded模式,打开本地库
				db4o_server = Db4o.openServer(_file, _port);
				_log.debug("# openServer("+_port+")..."+_file);
				if (_port>0 && _usr!=null && _pwd!=null) {
					db4o_server.grantAccess(_usr,_pwd);	//授权
					_log.debug("# grantAccess("+_usr+")...ok");
				}
			}		
			for(int i=0; i<this._maxSize; i++){	//打开多个数据库连接,尝试最大连接数
				ObjectContainer oc = this.m_open();
				db4o_pool.add(oc);
			}
			_log.debug("# start()...ok/"+db4o_pool.size());
		}
	}
	public void stop() {
		synchronized(this){
			for(Iterator i=db4o_pool.iterator(); i.hasNext(); ) {
				ObjectContainer oc = (ObjectContainer)i.next();
				oc.close();
			}		
			db4o_pool.clear();	
			db4o_pool = null;//全部清除		
			if (db4o_server!=null) {
				_log.debug("* close()...server");
				db4o_server.close();
				db4o_server = null;
			}
			_log.debug("* stop()...ok/"+db4o_mode);
		}
		
	}
	protected ObjectContainer m_open() throws IOException {
		ObjectContainer oc = null;
		if (db4o_server!=null) {	//已经打开
			oc = db4o_server.openClient();
			db4o_count++;
		}else if (_host!=null && _usr!=null && _pwd!=null) {
			oc = Db4o.openClient(_host, _port, _usr, _pwd);
			db4o_count++;
		}else {
			throw new IllegalArgumentException("need to set host,port,usr,pwd"); 
		}
		_log.debug("# m_open()..."+oc);
		return oc;
	}
	protected void m_close(ObjectContainer oc) {
		oc.close();		db4o_count--;
		_log.debug("* m_close()..."+oc);
	}
	protected void m_commit(ObjectContainer oc) {
		oc.commit();	//确保完成最后修改部分;
		_log.debug("* m_commit()..."+oc);
	}
	//-------------------------------------
	public synchronized ObjectContainer getConnection() throws Exception {
		if (db4o_pool==null) {
			throw new RuntimeException("(db4o_pool==null)");
		}
		while(db4o_pool.size()==0 && db4o_count>=_maxSize) {
			_log.warn("getConnection()...wait/size=0,count="+db4o_count);
			wait(1000);
		}
		ObjectContainer oc = null;
		if (db4o_pool.size()>0) {	//db4o_count<_maxSize
			Object obj = db4o_pool.remove(0);
			oc = (ObjectContainer)obj;
		}else {
			oc = m_open();
		}
		return oc;
	}
	public synchronized void closeConnection(ObjectContainer oc) {
		this.m_commit(oc);			//保险起见;
		if (db4o_pool.size() < this._minSize) {
			db4o_pool.add(oc);	//添加到连接池中;
			_log.debug("# closeConnection()...pooled 池化");
		}else {
			m_close(oc);		//直接释放
			_log.debug("# closeConnection()...closed 释放");
		}		
		notify();
	}
	//-------------------------------------
	static Random RAND = new Random(113);
	static class TJob extends Thread {
		Db4oPoolInf _pool = null;
		
		public TJob(Db4oPoolInf pool) {
			_pool = pool;
		}
		public void run() {
			ObjectContainer oc = null;
			try {
				oc = _pool.getConnection();//释放
				oc.set("Hello "+this.getName());
				oc.commit();	//奇怪,没有设置进去?? # run()...q:0
				ObjectSet os = oc.query(String.class);
				_log.debug("# run()...q:"+os.size());
				Util.sleepMSec(RAND.nextInt(500)+500);	//随机等待一定时间,模拟实际操作
				_log.debug("# run()...end");
			}catch(Exception e){
				e.printStackTrace();
			}finally{
				_pool.closeConnection(oc);	//释放
			}			
		}
	}
	public static void main(String[] args) throws IOException {
		Util.configureClassPath("res/log4j.properties");
		Db4oPool pool = new Db4oPool("db4o/pool/Db4oPool.yap");
		try {
			pool.setMinSize(3);
			pool.setMaxSize(5);
			pool.set_port(8888);	//可选,运行外部访问;
			pool.set_usr("USER");	//可选
			pool.set_pwd("PASS");	//可选
			pool.start();
			//多线程测试
			Thread[] tt = new Thread[20];
			for(int i=0; i<tt.length; i++) {
				tt[i] = new TJob(pool);
				tt[i].start();
			}
			_log.debug("------- wait for join ------");
			for(int i=0; i<tt.length; i++) {
				tt[i].join();
			}
		}catch(Exception e) {
			e.printStackTrace();
		}finally{
			pool.stop();
		}
		_log.debug("--------- END -------");
	}
}
需要的辅助类如下,用于配置log4j以及随机等待。
class Util {
	protected static Log _log = LogFactory.getLog(Util.class);
	public static void configureClassPath(String cfg) throws IOException {
    	//格式: com/bs2/core/my.properties
        InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream(cfg);
        if (is==null)	throw new IOException("Not Found in ClassPath:"+cfg);
        Properties props = new Properties();
        try { props.load(is); }finally{ is.close(); }
        PropertyConfigurator.configure(props);
        _log.debug("# configureClassPath()..."+cfg);
    }
	public static void sleepMSec(int msec) {
		try {
			_log.debug("# sleepMSec("+msec+")...");
			Thread.sleep(msec);
		} catch (InterruptedException e) {
			// 忽略
		}
	}	
}
分享到:
评论
2 楼 zeroliu 2007-01-19  
这种连接池方式被否决了。两个问题:性能、有状态!

A:虎无名还在不在? 很重要的事情,大家还知道他的 blog 地址吗?
A:找到了 db4o team 正在开会,讨论到这个问题了。 
B:什么问题?String等简单类型不能直接保存的问题?
A:不是,在研究 C/S 性能问题。

A:无名在不在? 老外否定了我们辛辛苦苦拉扯大的 con pool , 原因是:每个 session 都是有状态的
B:是不是,还有信息缓存在con中,为了提供效率;
A:yes
B:conn与session相关性很强,而不象jdbc中conn,statement,等多级别的;
A:但是,C/S 模式下,性能的确不高。 看来 db4o 的确不是为 web app 开发的。
A:我觉得 web app 下肯定要 c/s 模式,要不多线程就 lock 了 
B:大概明白了,先吃饭去;)连接池已经有锁了呀,关键是,不知道它的这些状态信息,保存多久;
A:我是说,如果为了效率而使用嵌入式模式,在 web app 下肯定要 lock 数据库文件。
A:ok
1 楼 zeroliu 2006-12-06  
后来经过测试,db4o似乎不能设置简单类型(String,Integer等),而只能是集合类型,或者自定义Bean。这似乎是db4o刻意为之。把上述源代码种的 oc.set("Hello "+this.getName());  
改为:oc.set(new HashMap()); 就可以了。

相关推荐

    db4o使用指南

    "db4o 使用指南" db4o 是一个开源的面向对象数据库,能够轻松地将 Java 对象持久化到数据库中。本文将详细介绍 db4o 的安装、启动、查询方式、对象持久化、数据库文件结构、主要包结构等知识点。 一、db4o 安装和...

    Db4o的简单操作项目

    Db4o,全称为“Database for Objects”,是一个开源的对象数据库管理系统,主要应用于Java和.NET平台。这个项目专注于提供一种简单的方式来存储和检索Java对象,无需SQL或其他中间映射层。在“Db4o的简单操作项目”...

    db4o8.0以及db4o中文指南

    **db4o 8.0 详解及中文指南** db4o(Database for Objects)是一款开源的对象数据库系统,它允许开发者直接将Java或.NET对象存储到数据库中,无需进行ORM(对象关系映射)。db4o的目标是简化数据管理,提供更接近...

    db4o-8.0-java

    **db4o(Database for Objects)** 是一个开源的对象数据库管理系统(Object-Relational Mapping,ORM),它允许开发者直接在Java或.NET平台上存储和检索Java对象或.NET对象,无需进行SQL查询或者映射过程。db4o的...

    db4o-7.12-tutorial

    ### db4o-7.12 教程详解 #### 一、db4o简介与安装 db4o是一款开源的对象数据库系统,支持Java、.NET 和 Mono等平台。本教程旨在帮助用户快速掌握db4o的基本用法,并提供丰富的资源以支持开发者深入学习。 在开始...

    DB4O管理工具

    DB4O(Database for Objects)是一款开源的对象数据库管理系统(Object-Relational Mapping,ORM),它允许开发者将Java或.NET对象直接存储到磁盘上,无需转换为传统的表和列的结构。DB4O的设计理念是简化数据存储,...

    db4o for java

    在实际使用中,开发者可以下载db4o的库文件(如压缩包中的"db4o-8.0"),将其引入到项目中,然后通过简单的API调用来实现对象的存储和查询。尽管db4o已经停止了官方的更新和支持,但它的设计理念和实现方式仍然对...

    db4o .net3.5

    db4o的.net3.5版本确保了与该框架的兼容性,使开发者能够利用其丰富的特性和库来实现对象持久化。 ### 3. db4o-7.4-net35.msi 这个文件是db4o 7.4版本针对.NET 3.5的安装程序。msi文件是Microsoft Installer格式,...

    对象数据库db4o对象数据库db4o

    5. **分布式数据库**:db4o支持多客户端并发访问,可以在分布式环境中运行,实现数据的共享和同步。 6. **动态模式**:db4o允许在运行时动态添加新类和字段,无需预先定义表结构,具有很好的灵活性。 ### 示例程序...

    db4o中文指南

    db4o是一个专为Java和.NET开发者设计的开源、轻量级的纯面向对象数据库引擎,提供了一种简单易用的方式来实现对象持久化。这款数据库引擎已被验证具备优秀的性能,根据描述中的基准测试,db4o在与传统持久化方案的...

    db4o开发指南和各种实例

    通过NQ,可以方便地实现对对象属性的匹配,如查询所有年龄大于30的人,只需创建一个年龄为30的对象,然后使用db4o的query()方法进行查找。 **三、SDOA(SODA - Simple Object Database Access)** SDOA是db4o提供的...

    db4o 权威指南

    《db4o 权威指南》是一本深入探讨db4o这一开源面向对象数据库系统的专业书籍,对于Java开发者来说尤其有价值。db4o是Database for Objects的缩写,它允许开发者以自然、直观的方式存储和检索Java对象,无需编写SQL...

    DB4O Java开发应用

    - 打开一个DB4O库:首先,你需要创建一个`Configuration`实例,并使用`Db4o.openServer()`或`Db4o.openClient()`方法来连接或打开数据库。这通常涉及到指定数据库的URL、端口以及配置参数。 - 存储对象:使用`...

    DB4O笔记+常用JAR包

    5. **分布式能力**:DB4O支持多客户端共享同一数据库,可以实现数据的分布式存储和访问。 6. **内存优化**:DB4O能根据需要动态加载和卸载对象,节省内存资源。 7. **事务支持**:DB4O提供ACID(原子性、一致性、...

    非常好的Db4o资料,适合想研究Db4o的同学

    Db4o,全称为“Database for Objects”,是一个开源的对象数据库系统,专为.NET和Java平台设计。它允许开发者直接在对象上进行数据操作,而无需传统的ORM(对象关系映射)层,简化了数据存储和检索的过程。这个...

    DB4o 数据库实例

    DB4o(Database for Objects)是一款开源的对象数据库系统,它允许开发者直接将对象持久化到数据库中,无需进行额外的映射或者数据访问层(DAL)的开发。这个数据库系统设计的目标是简化对象关系映射(ORM)的过程,...

    java数据库(db4o)

    对于学习和理解对象数据库以及如何在Java应用程序中实现对象持久化的开发者来说,db4o仍然是一个有价值的参考资料。在压缩包中的“db4o”文件可能包含了db4o的库文件、示例代码、文档等资源,可以帮助深入理解和使用...

    DB4O 8.0 Object Manager Enterprise

    db4o-8.0-tutorial.pdf 是该版本的官方教程文档,它涵盖了DB4O 8.0的主要特性和使用方法,包括如何配置、连接、查询和管理数据库。通过这份教程,用户可以深入理解DB4O的工作原理,学习如何将对象持久化到数据库中,...

    Db4o (net)类库

    为了使用Db4o,开发者需要将对应的DLL添加到项目引用中,并根据项目需求配置数据库连接和存储参数。 总的来说,Db4o是一个强大的对象数据库解决方案,它简化了.NET开发中的数据管理,使得对象模型和数据库模型保持...

Global site tag (gtag.js) - Google Analytics