使用JOTM實現分散式事務的例子

21ca發表於2009-04-15
import java.sql.Connection;
import javax.transaction.TransactionManager;
import javax.transaction.UserTransaction;
import org.enhydra.jdbc.standard.StandardXADataSource;
import org.hsqldb.Server;
import org.objectweb.jotm.Jotm;
import org.springframework.jdbc.core.JdbcTemplate;

public class XADataSourceTest {

    public static void main(String[] args) throws Exception {
        startDataBase();
       
        //建立J他的UserTransaction和TransactionManager。
        //下面會使用UserTransaction進行事務的提交和回滾。
        //TransactionManager用來管理事務源。
        Jotm jotm = new Jotm(true, false);
        TransactionManager transactionManager = jotm.getTransactionManager();
        UserTransaction utx = jotm.getUserTransaction();
       
        //建立一個分散式資料來源 XADataSource
        StandardXADataSource dataSource1 = new StandardXADataSource();
        dataSource1.setDriverName("org.hsqldb.jdbcDriver");
        dataSource1.setUser("sa");
        dataSource1.setUrl("jdbc:hsqldb:testdb1");
        //將該資料來源加入到TransactionManager管理範圍內
        dataSource1.setTransactionManager(transactionManager);
               
        StandardXADataSource dataSource2 = new StandardXADataSource();
        dataSource2.setDriverName("org.hsqldb.jdbcDriver");
        dataSource2.setUser("sa");
        dataSource2.setUrl("jdbc:hsqldb:testdb2");
        dataSource2.setTransactionManager(transactionManager);
       
        //得到兩個分散式Connection
        Connection cn1 = dataSource1.getXAConnection().getConnection();
        Connection cn2 = dataSource2.getXAConnection().getConnection();
       
        try{
            cn1.createStatement().execute("DROP TABLE table1");
            cn2.createStatement().execute("DROP TABLE table2");
        }catch(Exception e){}
        cn1.createStatement().execute("CREATE TABLE table1(id int primary key, money int)");
        cn2.createStatement().execute("CREATE TABLE table2(id int primary key, money int)");
       
        //插入初始資料。
        cn1.createStatement().execute("INSERT INTO table1 VALUES(1, 50)");
        cn2.createStatement().execute("INSERT INTO table2 VALUES(1, 50)");
       
        utx.begin();
        try{
            cn1.createStatement().execute("UPDATE table1 SET money=money-10 WHERE id=1");
            cn2.createStatement().execute("UPDATE table2 SET money=money+10 WHERE id=1");
            //模擬丟擲一個業務異常
            int a = 1 / 0;
            utx.commit();
        }catch(Exception e) {
            utx.rollback();
        }
       
        System.out.println(new JdbcTemplate(dataSource1).queryForInt("SELECT money FROM table1 WHERE id=1"));
        System.out.println(new JdbcTemplate(dataSource2).queryForInt("SELECT money FROM table2 WHERE id=1"));
    }

    //啟動HSQL,其中有兩個資料庫testdb1和testdb2。
    private static void startDataBase() {
        Server.main(new String[]{"-database.0", "hsqldb/testdb1", "-dbname.0", "testdb1",  "-database.1", "hsqldb/testdb2", "-dbname.1", "testdb2"});
    }

}

執行結果為:
50
50

說明事務回滾了。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10742815/viewspace-589259/,如需轉載,請註明出處,否則將追究法律責任。

相關文章