天天看點

bbosspersistent 性能初探

針對bbosspersistent,在oracle 10上做了一個簡單的性能測試:

環境配置:

連接配接池最大連接配接數設定為10

連接配接池初始連接配接數位2

測試場景:

300個線程并發往一張3字段的表中插入資料,每個線程執行3條記錄插入操作

測試結果:

插入完畢後,統計結果如下

不使用事務 :357條/秒

使用RW_TRANSACTION事務:820條/秒

測試程式:

package com.frameworkset.common.poolman;

import javax.transaction.RollbackException;

import com.frameworkset.orm.transaction.TransactionManager;

/**
 * 
 * <p>Title: CurrentTest.java</p>
 *
 * <p>Description: </p>
 *
 * <p>Copyright: Copyright (c) 2007</p>
 * @Date 2010-8-2 下午12:02:44
 * @author biaoping.yin
 * @version 1.0
 */
public class CurrentTest {
	public static void main(String[] args) throws InterruptedException {

//		for(int j = 0; j < 300; j ++)
//		{
//			CurrentTest i = new CurrentTest();
//			i.test(false);
//		}
		
		for(int j = 0; j < 300; j ++)
		{
			CurrentTest i = new CurrentTest();
			i.test(true);
		}

	}
	
	public void test(boolean usetx)
	{
		if(!usetx)
		{
			Task t = new Task();
			t.start();
		}
		else
		{
			TXTask t = new TXTask();
			t.start();
		}
			
	}
	static class Task extends Thread
	{

		/* (non-Javadoc)
		 * @see java.lang.Thread#run()
		 */
		@Override
		public void run() {
			DBUtil db = new DBUtil();
		
			try {

				db.executeInsert("insert into TEST_CURRENT(id,name) values(10,'test')");
				
				db.executeInsert("insert into TEST_CURRENT(id,name) values(10,'test')");
				
				db.executeInsert("insert into TEST_CURRENT(id,name) values(10,'test')");
				
				db.executeInsert("insert into TEST_CURRENT(id,name) values(10,'test')");

			} catch (Throwable e) {

				e.printStackTrace();
			}
			
		}
		
	}
	
	static class TXTask extends Thread
	{

		/* (non-Javadoc)
		 * @see java.lang.Thread#run()
		 */
		@Override
		public void run() {
			DBUtil db = new DBUtil();
			TransactionManager tm = new TransactionManager();
			try {
				tm.begin(tm.RW_TRANSACTION);
				db.executeInsert("insert into TEST_CURRENT(id,name) values(10,'test')");
				
				db.executeInsert("insert into TEST_CURRENT(id,name) values(10,'test')");
				
				db.executeInsert("insert into TEST_CURRENT(id,name) values(10,'test')");
				
				db.executeInsert("insert into TEST_CURRENT(id,name) values(10,'test')");
				tm.commit();
			} catch (Throwable e) {
				try {
					tm.rollback();
				} catch (RollbackException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				e.printStackTrace();
			}
			
		}
		
	}
}      

測試結果說明:

為什麼啟用RW_TRANSACTION事務後性能要好于沒有啟用事務的情況呢,這是由于資料庫連接配接池的特性決定,連接配接池中的連接配接資源是一種共享資源,要想擷取一個db connection,首先要獲得pool中的共享鎖,擷取完畢後再釋放鎖。在沒有事務上下文的情況下,每個db操作都是一個獨立的事務,都會從db pool中擷取連接配接,是以擷取鎖的次數比較頻繁,這樣就會導緻性能下降;相反一個RW_TRANSACTION上下文中隻會擷取一個db connection,隻有一次擷取鎖的情況,性能要好很多。

影響持久層操作性能因素分析:

1.頻繁地申請連接配接池中連接配接會導緻性能降低

2.頻繁地釋放資料庫連接配接到連接配接池中也會導緻性能降低

3.開啟連接配接池中連接配接校驗特性會導緻新能降低

連接配接池連接配接在以下情況下會執行校驗邏輯:

a.申請連接配接(預設開啟),可以通過以下方式進行控制

<testOnBorrow>false</testOnBorrow>

b.釋放連接配接(預設關閉),可以通過以下方式進行控制(目前bboss沒有開放改配置開關,即使配置也無效)

<testOnReturn>false</testOnReturn>

c.空閑連接配接回收掃描操作(預設關閉),可以通過以下方式進行控制

<testWhileIdle>true</testWhileIdle>

同時我們也可以通過指定validationQuery屬性來控制執行校驗操作時是否執行一條指定的sql語句,來校驗連接配接的可用性,而且在執行的時候會占用共享鎖,這個性能開銷比較大。

我們可以不配置validationQuery屬性來提升系統性能

<!-- 
    	連結有效性檢查sql語句
     -->
    <validationQuery>select 1 from dual</validationQuery>      

4.開啟強制回收長時間占用連接配接機制,會對性能有一定的影響,屏蔽方法:

<removeAbandoned>false</removeAbandoned>

removeAbandoned開關主要在開發環境下開啟,用來檢測是否有洩露的事務連結,并且在連接配接占用比較多的情況下,回收占用時間較長的連結,生産環境下必須将removeAbandoned設定為false。

上述4個因素也可以通過在程式設計過程采用資料庫事務來優化性能,将密集的資料操作包含在事務中,bboss資料庫事務開啟方法:

TransactionManager tm = new TransactionManager();
			try {
				tm.begin(tm.RW_TRANSACTION);
                              //db操作
                               tm.commit();
			} catch (Throwable e) {
				try {
					tm.rollback();
				} catch (RollbackException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				e.printStackTrace();
			}
      

或者

TransactionManager tm = new TransactionManager();
			try {
				tm.begin();
                              //db操作
                               tm.commit();
			} catch (Throwable e) {
				try {
					tm.rollback();
				} catch (RollbackException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				e.printStackTrace();
			}
      

詳細的資料庫事務請參考文檔

bbossgroups教育訓練.ppt

中的事務管理部分

同時也可以參考另一篇文章《

bbossgroups持久層架構連結池配置優化政策之一 空閑連結回收配置

5.補充說明

如果你的應用部署在weblogic或者websphere下面,盡量使用應用伺服器本身的資料源,bboss持久層中配置外部資料源的方法參考文檔《

bboss persistent通過jndi引用外部資料源(datasource)方法