使用Atomikos进行两阶段提交(2PC)配置 [英] Two-phase commit (2PC) configuration with Atomikos

查看:153
本文介绍了使用Atomikos进行两阶段提交(2PC)配置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个示例应用程序来测试两阶段提交(2PC).我已经从互联网上获取了此处使用的代码位.我正在将Spring,Hibernate和Atomikos与MySQL用作后端.我正在使用两个数据库,故意对第二个数据库进行调用无法检查是否对第一个数据库调用进行了回滚.不幸的是,它似乎不起作用.有人可以指向我一些示例代码的链接吗?

I am creating a sample application to test two-phase commit (2PC). I have taken the code bits used here from the Internet. I am using Spring, Hibernate and Atomikos with MySQL as the backend. I am using two databases and deliberately making the call to the second database fail to check whether the first database call gets rolled back. Sadly it doesn't seem to work. Can some one point me to some links with some sample code?

以下是我的配置:
Hibernate会话工厂:

Following is my configuration:
The Hibernate session factories:

<bean id="sessionFactory1" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource">
        <ref bean="dataSource1"/>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.connection.isolation">3</prop>    
            <prop key="hibernate.current_session_context_class">jta</prop>    
            <prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</prop>    
            <prop key="hibernate.transaction.manager_lookup_class">com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup</prop> 
            <prop key="hibernate.connection.release_mode">on_close</prop>
        </props>
    </property>

    <property name="mappingResources">
        <list>
            <value>/hibernate/Stock.hbm.xml</value>
        </list>
    </property>
</bean>

<bean id="sessionFactory2" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource">
        <ref bean="dataSource2"/>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.connection.isolation">3</prop>    
            <prop key="hibernate.current_session_context_class">jta</prop>    
            <prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</prop>    
            <prop key="hibernate.transaction.manager_lookup_class">com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup</prop> 
            <prop key="hibernate.connection.release_mode">on_close</prop>
        </props>
    </property>

    <property name="mappingResources">
        <list>
            <value>/hibernate/Stock1.hbm.xml</value>
        </list>
    </property>
</bean>

dataSource配置:

The dataSource configuration:

<bean id="dataSource1" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">        
    <!-- set an arbitrary but unique name for the datasource -->       
    <property name="uniqueResourceName"><value>XADBMS1</value></property>        
    <!-- set the underlying driver class to use, in this example case we use MySql  -->       
    <property name="xaDataSourceClassName">          
        <value>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</value>       
    </property>       
    <property name="xaProperties">           
    <!--   set the driver-specific XADataSource properties  (check your driver docs for more info)           -->                 
        <props>                         
            <prop key="user">${jdbc.username}</prop>                         
            <prop key="password">${jdbc.password}</prop>                         
            <prop key="URL" >${jdbc.url1}</prop>                 
        </props>      
    </property>           
    <!-- how many connections in the pool? -->       
    <property name="poolSize" value="3"/>    
</bean>

<bean id="dataSource2" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">        
    <!-- set an arbitrary but unique name for the datasource -->       
    <property name="uniqueResourceName"><value>XADBMS2</value></property>        
    <!-- set the underlying driver class to use, in this example case we use MySql  -->       
    <property name="xaDataSourceClassName">          
        <value>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</value>       
    </property>       
    <property name="xaProperties">           
    <!--   set the driver-specific XADataSource properties  (check your driver docs for more info)           -->                 
        <props>                         
            <prop key="user">${jdbc.username}</prop>                         
            <prop key="password">${jdbc.password}</prop>                         
            <prop key="URL" >${jdbc.url2}</prop>                 
        </props>      
    </property>           
    <!-- how many connections in the pool? -->       
    <property name="poolSize" value="3"/>    
</bean>

Spring JTA配置:

The Spring JTA configuration:

 <bean id="AtomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close">     
<!-- when close is called, should we force transactions to terminate or not?     -->   
   <property name="forceShutdown" value="false" /> 
</bean>  
<!--Also use Atomikos UserTransactionImp, needed to configure Spring   --> 
<bean id="AtomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">     
    <property name="transactionTimeout" value="300" /> 
</bean>

<!--Configure the Spring framework to use JTA transactions from Atomikos  --> 
<bean id="JtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">    
    <property name="transactionManager" ref="AtomikosTransactionManager" />    
    <property name="userTransaction" ref="AtomikosUserTransaction" /> 
</bean>  

我有两个DAOImpl,将上面定义的两个sessionFactory注入其中.以下是来自Java代码的调用:

I have two DAOImpl into which I inject the two sessionFactories defined above. Following is the call from the Java code:

public static void main( String[] args )
{
    ApplicationContext appContext = 
            new ClassPathXmlApplicationContext("spring/config/appContext.xml");

    StockBo stockBo = (StockBo)appContext.getBean("stockBo1");
    StockBo stockBo2 = (StockBo)appContext.getBean("stockBo2");

    /** insert **/
    Stock stock = new Stock();
    stock.setStockCode("7668");
    stock.setStockName("HAIO");
    stockBo.save(stock);

    Stock stock1 = new Stock();
    //stock1.setStockCode("1668"); **Commented to fail the second db insert**
    stock1.setStockName("AAIO");
    stockBo2.save(stock1);
}

任何指针都会有很大帮助.

Any pointers would be of great help.

谢谢

推荐答案

要获得所需的行为,您需要在同一事务内执行DAO调用,例如,如下所示:

To get the behaviour you expect you need to perform your DAO calls inside the same transaction, for example, as follows:

final StockBo stockBo = (StockBo)appContext.getBean("stockBo1");
final StockBo stockBo2 = (StockBo)appContext.getBean("stockBo2");
TransactionTemplate tx = new TransactionTemplate(appContext.getBean(PlatformTransactionManager.class);

tx.execute(new TransactionCallback<Void>() {
    public Void doInTransaction(TransactionStatus ts) {
        /** insert **/
        Stock stock = new Stock();
        stock.setStockCode("7668");
        stock.setStockName("HAIO");
        stockBo.save(stock);

        Stock stock1 = new Stock();
        //stock1.setStockCode("1668"); **Commented to fail the second db insert**
        stock1.setStockName("AAIO");
        stockBo2.save(stock1);

       return null;
    }
});

此外,我认为您不需要以下行,因为您使用Spring配置了Hibernate:

Also, I think you don't need the following lines since you configure Hibernate with Spring:

<prop key="hibernate.current_session_context_class">jta</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</prop> 
<prop key="hibernate.transaction.manager_lookup_class">com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup</prop>
<prop key="hibernate.connection.release_mode">on_close</prop>  

另请参见:

这篇关于使用Atomikos进行两阶段提交(2PC)配置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆