2012-04-18 75 views
3

我正在創建一個示例應用程序來測試兩階段提交(2PC)。我已經從互聯網上使用了這裏使用的代碼位。我使用Spring作爲後端,使用Hibernate和Atomikos。我正在使用兩個數據庫並故意讓對第二個數據庫的調用無法檢查第一個數據庫調用是否回滾。可悲的是,它似乎並沒有工作。有人可以指向一些示例代碼的鏈接嗎?與Atomikos的兩階段提交(2PC)配置

以下是我的配置:
Hibernate的會話工廠:

<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> 

數據源配置:

<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配置:

<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我注入了兩個sessi上面定義的onFactories。以下是來自Java代碼的調用:

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); 
} 

任何指針都會有很大的幫助。

感謝

回答

3

爲了讓你期望你需要執行你的DAO調用同一個事務中,比如行爲,如下所示:

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; 
    } 
}); 

另外,我覺得你不需要下面幾行,因爲你與配置Hibernate的春天:

<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> 

另請參見:

+0

感謝axtavt用於響應,也爲linnk – shashikanthb 2012-04-19 06:48:00