請教一個關於多資料來源的分散式事務問題?

mindfloating發表於2006-04-03
現實中有兩個資料庫位於不同的資料庫服務主機上,因為有些業務操作涉及到對這兩個資料庫的資料插入等,而且它們應該包含在一個事務中

完成。我現在做了一個例子模擬跨資料來源的分散式事務管理,但最後不能對資料庫中的表進行寫操作,查詢就可以。我下面詳細描述一下我這

個例子程式 ,看看我的做法有什麼問題嘛?

1、後臺資料庫 SQL Server 2000 + sp3,我建立了2個資料庫來模擬兩個資料來源,每個資料庫上一張表,需要對這兩張表完成分別執行一個插入操

作,並放在一個事務中,即要麼兩張表都插入了新的資料,要麼都別插入。

2、持久層用Hibernate對映(下面是詳細對映配置檔案)

-------資料來源 1 的hibernate.cfg.xml----------------
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hibernate-configuration
PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd">

<hibernate-configuration>
<session-factory >

<property name="connection.datasource">TestDB</property>
<property name="transaction.factory_class">net.sf.hibernate.transaction.JTATransactionFactory</property>
<property name="transaction.manager_lookup_class">net.sf.hibernate.transaction.WeblogicTransactionManagerLookup</property>
<property name="dialect">net.sf.hibernate.dialect.SQLServerDialect</property>
<property name="hibernate.connection.provider_class">net.sf.hibernate.connection.DatasourceConnectionProvider</property>
<property name="hibernate.jndi.class">weblogic.jndi.WLInitialContextFactory</property>
<property name="hibernate.jdbc.fetch_size">100</property>
<property name="hibernate.jdbc.batch_size">50</property>
<property name="show_sql">true</property>

<mapping resource="test/Addressbook.hbm.xml" />

</session-factory>
</hibernate-configuration>

-------資料來源 1 的hibernate.cfg.xml----------------

-------資料來源 2 的hibernate.cfg.xml----------------
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hibernate-configuration
PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd">

<hibernate-configuration>
<session-factory >
<property name="connection.datasource">txyyDB</property>
<property name="transaction.factory_class">net.sf.hibernate.transaction.JTATransactionFactory</property>
<property name="transaction.manager_lookup_class">net.sf.hibernate.transaction.WeblogicTransactionManagerLookup</property>
<property name="dialect">net.sf.hibernate.dialect.SQLServerDialect</property>
<property name="hibernate.connection.provider_class">net.sf.hibernate.connection.DatasourceConnectionProvider</property>
<property name="hibernate.jndi.class">weblogic.jndi.WLInitialContextFactory</property>
<property name="hibernate.jdbc.fetch_size">100</property>
<property name="hibernate.jdbc.batch_size">50</property>
<property name="show_sql">true</property>

<mapping resource="test/Txyy.hbm.xml" />

</session-factory>
</hibernate-configuration>

-------資料來源 2 的hibernate.cfg.xml----------------


3、應用伺服器採用Weblogic 8.1

在伺服器中分別配置了2個連線池,分別對應兩個資料來源,資料庫驅動採用了XA的SQL驅動。

4、一個例子程式,如下:

-----------例子程式原始碼-----------------------
package test;

import net.sf.hibernate.*;
import net.sf.hibernate.cfg.Configuration;
import java.io.*;
import java.util.*;
import util.NamingContext;
import javax.transaction.*;
import javax.naming.*;

public class MyTest {

public static SessionFactory sf1

public static SessionFactory sf2;

static{
try{
Configuration config1 = new Configuration().configure("/hfcfg/hibernate.cfg.xml"); // 建立資料來源1的Config物件
Configuration config2 = new Configuration().configure("/cfg/hibernate.cfg.xml"); // 建立資料來源2的Config物件

// 根據配置建立對應2個資料來源的SessionFactory物件
sf1= config.buildSessionFactory();
sf2 = config1.buildSessionFactory();

}catch(Exception e){e.printStackTrace();}
}

MyTest(){}

// 主要的業務測試方法,分別對兩個資料來源中的兩張表執行插入操作,並置於同一事務下
public List test() throws Exception{

Context ctx = util.NamingContext.getInitialContext();
UserTransaction tx =(UserTransaction) ctx.lookup("javax.transaction.UserTransaction");

if(tx != null) {
System.out.println("獲取UserTransaction例項 = " + tx.toString() + "--" + tx.getClass());
}

// 事務開始
tx.begin();
Session s1 = sf1.openSession();
Session s2 = sf2.openSession();

List addressList = null;
try{

addressList = session.find("from Addressbook as c order by c.name asc");

addressbook ar = new Addressbook();
ar.setAddress("中山大學");
ar.setName("hf");
ar.setPhone("111");
s1.save(ar);

Txyy ty = new Txyy();
ty.setYyms("test");
s2.save(ty);

for (Iterator it = addressList .iterator(); it.hasNext(); ) {
System.out.println(((Addressbook) it.next()).getName());
}

tx.commit(); // 事務提交

}catch (Exception e) {
if (tx != null) {
System.out.println("||||------事務回滾了--------||||");
tx.rollback();
}
throw e;
}finally {
s1.close();
s2.close();
}
return addressList;
}
}


我最後寫了一個測試JSP,僅僅就是呼叫這個MyTest類的Test方法,但伺服器控制檯打出的資訊,沒有任何異常,查詢結果列印出來了,但插入

操作沒有執行,資料庫中表的內容未發生任何改變,一直很疑惑,不知問題出在哪裡?

相關文章