-1

我想配置兩個數據源之一是Oracle,一個是My-SQL Spring JTA中的事務管理器執行2階段提交,以便任何數據源的任何一個事務都失敗,並且Spring JTA需要對這兩個數據源執行回滾如何使用Spring JTA將兩個數據源配置爲單個事務管理器,以便對異常這兩個數據源都得到回滾

*聽說atomikos我們可以用來配置這種場景 請提供一些配置代碼是什麼,這將有助於執行此代碼*

GIT中的URL爲整個代碼: https://github.com/mageshsrinivasulu/poc

彈簧-beans.xml文件:

<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:tx="http://www.springframework.org/schema/tx" 
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
http://www.springframework.org/schema/tx 
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"> 


<bean class="org.springframework.beans.factory.config 
.PropertyPlaceholderConfigurer"> 
    <property name="location" value="classpath:Application.properties" /> 
</bean> 

<bean id="oracleSessionFactory" 
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="oracleDataSource" /> 
    <property name="mappingResources"> 
     <list> 
      <value>persons.hbm.xml </value> 
     </list> 
    </property> 

    <property name="hibernateProperties"> 
     <props> 
      <prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop> 
      <prop key="hibernate.autocommit">false</prop> 
      <!-- <prop key="hibernate.current_session_context_class">thread</prop> --> 
      <prop key="hibernate.c3p0.min_size">5</prop> 
      <prop key="hibernate.c3p0.max_size">10</prop> 
      <prop key="hibernate.c3p0.timeout">300</prop> 
     </props> 
    </property> 

</bean> 

<bean id="mysqlSessionFactory" 
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="mysqlDataSource" /> 
    <property name="mappingResources"> 
     <list> 
      <value>persons.hbm.xml </value> 
     </list> 
    </property> 
    <property name="hibernateProperties"> 
     <props> 
      <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> 
      <prop key="hibernate.autocommit">false</prop> 
      <!-- <prop key="hibernate.current_session_context_class">thread</prop> --> 
      <prop key="hibernate.c3p0.min_size">5</prop> 
      <prop key="hibernate.c3p0.max_size">10</prop> 
      <prop key="hibernate.c3p0.timeout">300</prop> 
     </props> 
    </property> 
</bean> 
<!-- Creating TransactionManager Bean, since JDBC we are creating of type 
    DataSourceTransactionManager --> 



<bean id="oracleTransactionManager" 
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
    <property name="dataSource" ref="oracleDataSource" /> 

</bean> 

<bean id="mysqlTransactionManager" 
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
    <property name="dataSource" ref="mysqlDataSource" /> 
</bean> 


<bean id="oracleDataSource" 
    class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    <property name="driverClassName" value="${oracle.hibernate.connection.driver_class}" /> 
    <property name="url" value="${oracle.hibernate.connection.url}" /> 
    <property name="username" value="${oracle.Username}" /> 
    <property name="password" value="${oracle.Password}" /> 

</bean> 

<bean id="mysqlDataSource" 
    class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    <property name="driverClassName" value="${mysql.jdbc.driverClassName}" /> 
    <property name="url" value="${mysql.hibernate.connection.url}" /> 
    <property name="username" value="${mysql.Username}" /> 
    <property name="password" value="${mysql.Password}" /> 

</bean> 

<bean id="persons" class="com.bnym.aal.poc.spring_jta.Persons"> 
</bean> 

<bean id="App" class="com.bnym.aal.poc.spring_jta.App"> 
    <property name="springJtaDaoClass" ref="springJtaDaoClass" /> 
</bean> 

<bean id="springJtaDaoClass" class="com.bnym.aal.poc.spring_jta.springJtaDaoClass"> 
    <property name="oracleSessionFactory" ref="oracleSessionFactory" /> 
    <property name="mysqlSessionFactory" ref="mysqlSessionFactory" /> 
    <property name="oracleTransactionManager" ref="oracleTransactionManager" /> 
    <property name="mysqlTransactionManager" ref="mysqlTransactionManager" /> 
    <property name="persons" ref="persons" /> 
</bean> 

springJtaDaoClass

import java.io.Serializable; 
import java.util.List; 
import javax.sql.DataSource; 
import org.hibernate.Session; 
import org.hibernate.SessionFactory; 
import org.springframework.dao.DataAccessException; 
import org.springframework.jdbc.core.JdbcTemplate; 
import org.springframework.orm.hibernate4.HibernateTemplate; 
import org.springframework.transaction.PlatformTransactionManager; 
import org.springframework.transaction.TransactionDefinition; 
import org.springframework.transaction.TransactionStatus; 
import org.springframework.transaction.annotation.Propagation; 
import org.springframework.transaction.annotation.Transactional; 
import org.springframework.transaction.support.DefaultTransactionDefinition; 
package com.bnym.aal.poc.spring_jta; 

public class springJtaDaoClass implements Serializable 
{ 
/** 
* 
*/ 
private static final long serialVersionUID = 1L; 
private static SessionFactory oracleSessionFactory; 
private static SessionFactory mysqlSessionFactory; 
private HibernateTemplate oracleJdbcTemplateObject; 
private HibernateTemplate mysqlJdbcTemplateObject; 
private static Persons persons; 

public static SessionFactory getOracleSessionFactory() { 
return oracleSessionFactory; 
} 
public void setOracleSessionFactory(SessionFactory oracleSessionFactory) { 
springJtaDaoClass.oracleSessionFactory = oracleSessionFactory; 
this.oracleJdbcTemplateObject=new HibernateTemplate(oracleSessionFactory); 
} 
public static SessionFactory getMysqlSessionFactory() { 
return mysqlSessionFactory; 
} 
public void setMysqlSessionFactory(SessionFactory mysqlSessionFactory) { 
springJtaDaoClass.mysqlSessionFactory = mysqlSessionFactory; 
this.mysqlJdbcTemplateObject=new HibernateTemplate(mysqlSessionFactory); 
} 

public static PlatformTransactionManager oracleTransactionManager; 
public static PlatformTransactionManager mysqlTransactionManager; 

public static PlatformTransactionManager getOracleTransactionManager() { 
return oracleTransactionManager; 
} 
public static void setOracleTransactionManager(PlatformTransactionManager 
oracleTransactionManager) { 
springJtaDaoClass.oracleTransactionManager = oracleTransactionManager; 
} 
public static PlatformTransactionManager getMysqlTransactionManager() { 
return mysqlTransactionManager; 
} 
public static void setMysqlTransactionManager(PlatformTransactionManager 
mysqlTransactionManager) { 
springJtaDaoClass.mysqlTransactionManager = mysqlTransactionManager; 
} 
public static Persons getPersons() { 
return persons; 
} 
public static void setPersons(Persons persons) { 
springJtaDaoClass.persons = persons; 
} 

public void dbOracleAccess() 
{ 
TransactionDefinition oracledef= new DefaultTransactionDefinition(); 
TransactionStatus oraclestatus = 
oracleTransactionManager.getTransaction(oracledef); 

try 
{ 
Persons person1=getPersons().persons(1,"a","b","c","d"); 
oracleJdbcTemplateObject.save(person1); 
oracleTransactionManager.commit(oraclestatus); 
} 
catch (DataAccessException e) { 
System.out.println("Error in creating record, rolling back"); 
oracleTransactionManager.rollback(oraclestatus); 
throw e; 
} 

} 
public void dbMySqlAccess() 
{ 
TransactionDefinition mysqldef= new DefaultTransactionDefinition(); 
TransactionStatus 
mysqlstatus=mysqlTransactionManager.getTransaction(mysqldef); 

try 
{ 
Persons person2=getPersons().persons(2,"e","b","c","d"); 
mysqlJdbcTemplateObject.save(person2); 
mysqlTransactionManager.commit(mysqlstatus); 
} 
catch (DataAccessException e) { 
System.out.println("Error in creating record, rolling back"); 
mysqlTransactionManager.rollback(mysqlstatus); 
throw e; 
} 
} 
} 

回答

0

下面是上述問題的工作代碼:

爲Atomikos公司事務經理爲通過開箱一體化連接兩個數據來源單一的事務管理器將可在下面的GIT整個項目網址

https://github.com/mageshsrinivasulu/spring-jta.git

彈簧的beans.xml

<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:tx="http://www.springframework.org/schema/tx" 
xmlns:aop="http://www.springframework.org/schema/aop" 
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
http://www.springframework.org/schema/aop 
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd 
http://www.springframework.org/schema/tx 
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"> 

<bean 
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
    <property name="location" value="classpath:Application.properties" /> 
</bean> 

<bean id="oracleSessionFactory" 
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="oraclesDataSource" /> 
    <property name="mappingResources"> 
     <list> 
      <value>persons.hbm.xml </value> 
     </list> 
    </property> 

    <property name="hibernateProperties"> 
     <props> 
      <prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop> 
      <!-- <prop key="hibernate.autocommit">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.CMTTransactionFactory 
      </prop> 
      <prop key="hibernate.transaction.manager_lookup_class"> 
       com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup 
      </prop> 
      <!-- <prop key="hibernate.current_session_context_class">thread</prop> --> 
      <prop key="hibernate.c3p0.min_size">5</prop> 
      <prop key="hibernate.c3p0.max_size">10</prop> 
      <prop key="hibernate.c3p0.timeout">300</prop> 
     </props> 
    </property> 

</bean> 

<bean id="mysqlSessionFactory" 
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="mysqlDataSource" /> 
    <property name="mappingResources"> 
     <list> 
      <value>persons.hbm.xml </value> 
     </list> 
    </property> 
    <property name="hibernateProperties"> 
     <props> 
      <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> 
      <!-- <prop key="hibernate.autocommit">ture</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.CMTTransactionFactory 
      </prop> 
      <prop key="hibernate.transaction.manager_lookup_class"> 
       com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup 
      </prop> 

      <!-- <prop key="hibernate.current_session_context_class">thread</prop> --> 
      <prop key="hibernate.c3p0.min_size">5</prop> 
      <prop key="hibernate.c3p0.max_size">10</prop> 
      <prop key="hibernate.c3p0.timeout">300</prop> 
     </props> 
    </property> 

</bean> 



<tx:annotation-driven proxy-target-class="true" /> 

<tx:jta-transaction-manager 
    transaction-manager="atomikosTransactionManager" /> 

<tx:annotation-driven transaction-manager="atomikosTransactionManager" 
    proxy-target-class="true" /> 

<bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" 
    init-method="init" destroy-method="close"> 
    <property name="forceShutdown" value="false" /> 

</bean> 
<bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.J2eeUserTransaction"> 
    <property name="transactionTimeout" value="300" /> 

</bean> 


<tx:annotation-driven /> 
<bean id="transactionManager" 
    class="org.springframework.transaction.jta.JtaTransactionManager" 
    depends-on="atomikosTransactionManager,atomikosUserTransaction"> 
    <property name="transactionManager" ref="atomikosTransactionManager" /> 
    <property name="userTransaction" ref="atomikosUserTransaction" /> 
    <property name="allowCustomIsolationLevels" value="true" /> 

</bean> 

<bean id="mysqlDataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" 
    init-method="init" destroy-method="close"> 
    <property name="uniqueResourceName"> 
     <value>mySqlDataSource</value> 
    </property> 
    <property name="xaDataSourceClassName"> 
     <value>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</value> 
    </property> 
    <property name="xaProperties"> 
     <props> 
      <prop key="databaseName">sys</prop> 
      <prop key="serverName">localhost</prop> 
      <prop key="port">3306</prop> 
      <prop key="user">root</prop> 
      <prop key="password">magesh123</prop> 
      <prop key="url">jdbc:mysql://localhost:3306/sys</prop> 
     </props> 
    </property> 
    <property name="minPoolSize"> 
     <value>1</value> 
    </property> 
</bean> 


<bean id="oraclesDataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" 
    init-method="init" destroy-method="close"> 
    <property name="uniqueResourceName"> 
     <value>OracleDataSource</value> 
    </property> 
    <property name="xaDataSourceClassName"> 
     <value>oracle.jdbc.xa.client.OracleXADataSource</value> 
    </property> 
    <property name="xaProperties"> 
     <props> 
      <prop key="databaseName">XE</prop> 
      <prop key="serverName">localhost</prop> 
      <!-- <prop key="port">1521</prop> --> 
      <prop key="user">system</prop> 
      <prop key="password">magesh123</prop> 
      <prop key="URL">jdbc:oracle:thin:@localhost:1521:XE</prop> 
     </props> 
    </property> 
    <property name="minPoolSize"> 
     <value>1</value> 
    </property> 
</bean> 



<bean id="persons" class="com.bnym.aal.poc.spring_jta.Persons"> 
</bean> 

<bean id="App" class="com.bnym.aal.poc.spring_jta.App"> 
    <property name="springJtaDaoClass" ref="springJtaDaoClass" /> 
</bean> 

<bean id="springJtaDaoClass" class="com.bnym.aal.poc.spring_jta.springJtaDaoClass"> 
    <property name="oracleSessionFactory" ref="oracleSessionFactory" /> 
    <property name="mysqlSessionFactory" ref="mysqlSessionFactory" /> 
    <property name="atomikosTransactionManager" ref="transactionManager" /> 
    <property name="persons" ref="persons" /> 

</bean> 

springJtaDaoClass.java

package com.bnym.aal.poc.spring_jta; 

import java.io.Serializable; 
import org.hibernate.FlushMode; 
import org.hibernate.Hibernate; 
import org.hibernate.HibernateException; 
import org.hibernate.Session; 
import org.hibernate.SessionFactory; 
import org.hibernate.Transaction; 
import org.springframework.dao.DataAccessException; 
import org.springframework.orm.hibernate4.HibernateTemplate; 
import org.springframework.transaction.PlatformTransactionManager; 
import org.springframework.transaction.TransactionDefinition; 
import org.springframework.transaction.TransactionStatus; 
import org.springframework.transaction.annotation.Propagation; 
import org.springframework.transaction.annotation.Transactional; 
import org.springframework.transaction.support.DefaultTransactionDefinition; 

public class springJtaDaoClass implements Serializable { 
/** 
    * 
    */ 
private static final long serialVersionUID = 1L; 
private static SessionFactory oracleSessionFactory; 
private static SessionFactory mysqlSessionFactory; 

private HibernateTemplate oracleJdbcTemplateObject; 
private HibernateTemplate mysqlJdbcTemplateObject; 

private static Persons persons; 

public static SessionFactory getOracleSessionFactory() { 
    return oracleSessionFactory; 
} 

public void setOracleSessionFactory(SessionFactory oracleSessionFactory) { 
    springJtaDaoClass.oracleSessionFactory = oracleSessionFactory; 
    this.oracleJdbcTemplateObject = new 
HibernateTemplate(oracleSessionFactory); 
} 

public static SessionFactory getMysqlSessionFactory() { 
    return mysqlSessionFactory; 
} 

public void setMysqlSessionFactory(SessionFactory mysqlSessionFactory) { 
    springJtaDaoClass.mysqlSessionFactory = mysqlSessionFactory; 
    this.mysqlJdbcTemplateObject = new 
    HibernateTemplate(mysqlSessionFactory); 
} 

public static PlatformTransactionManager atomikosTransactionManager; 

public static PlatformTransactionManager getAtomikosTransactionManager() { 
    return atomikosTransactionManager; 
} 

public static void setAtomikosTransactionManager(PlatformTransactionManager 
    atomikosTransactionManager) { 
    springJtaDaoClass.atomikosTransactionManager = 
    atomikosTransactionManager; 
} 

public static Persons getPersons() { 
    return persons; 
} 

public static void setPersons(Persons persons) { 
    springJtaDaoClass.persons = persons; 
} 

@Transactional() 
public void daoWrapper() throws Exception { 
    atomikosTransactionManager = getAtomikosTransactionManager(); 
    TransactionDefinition def = new DefaultTransactionDefinition(); 
    TransactionStatus status = 
    atomikosTransactionManager.getTransaction(def); 
    Persons person1 = new Persons(); 
    person1.persons(2, "a", "b", "c", "d"); 
    try { 
     getMysqlSessionFactory().getCurrentSession().save(person1); 
     getOracleSessionFactory().getCurrentSession().save(person1); 
     atomikosTransactionManager.commit(status); 
    } catch (Exception e) { 
     System.out.println("Error in creating record, rolling back"); 
     atomikosTransactionManager.rollback(status); 
     e.printStackTrace(); 
    } 

} 
} 
0

您可以檢查出我的GitHub的鏈接全部樣本Web應用程序的第二階段(2PC)協議演示數據存儲在MySQL數據庫,然後在Oracle數據庫中保持ACID,如果oracle數據庫拋出異常,則在MySql數據庫中也會發生回滾

Git的樞紐鏈接,2PC示例Web應用程序 Two Phase (2PC) demo application

我沒有使用第三方JTA提供商,而不是我使用J2EE兼容的應用服務器JBoss作爲7 JTA服務。

相關問題