转载请注明出处:http://blog.csdn.net/l1028386804/article/details/48179319
Spring3+后不再对JTOM提供支持,所以可以改用Atomikos管理多数据源事务。
一.pom.xml
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>transactions-jdbc</artifactId>
<version>3.9.3</version>
</dependency>
二.applicationContext-atomikos.xml
<bean class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close" id="dataSource01">
<!-- Set unique name for this DataSource -->
<property name="uniqueResourceName"><value>oracle</value></property>
<!-- Set XADatasource class name -->
<property name="xaDataSourceClassName" value="oracle.jdbc.xa.client.OracleXADataSource" />
<property name="xaProperties">
<props>
<prop key="user">${jdbc.username01}</prop>
<prop key="password">${jdbc.password01}</prop>
<prop key="URL">${jdbc.url01}</prop>
</props>
</property>
<!-- set properties for datasource connection pool -->
<property name="poolSize" value="3" />
<!-- timeout after 20000 seconds -->
<property name="reapTimeout"><value>20000</value></property>
</bean>
<bean id="sessionFactory01"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource01" />
<property name="packagesToScan">
<list>
<value>com.cpframework.function.**.model.oracle</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.Oracle10gDialect
</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.current_session_context_class">jta</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</prop>
</props>
</property>
</bean>
<!-- oracleDAO -->
<bean id="hibernateDAO01" class="org.cpframework.dao.hibernate4.CP_Hibernate4DAOImpl">
<property name="sessionFactory" ref="sessionFactory01"></property>
</bean>
<bean class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close" id="dataSource02">
<!-- Set unique name for this DataSource -->
<property name="uniqueResourceName"><value>mysql</value></property>
<!-- Set XADatasource class name -->
<property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />
<property name="xaProperties">
<props>
<prop key="user">${jdbc.username02}</prop>
<prop key="password">${jdbc.password02}</prop>
<prop key="URL">${jdbc.url02}</prop>
</props>
</property>
<!-- set properties for datasource connection pool -->
<property name="poolSize" value="3" />
<property name="reapTimeout"><value>20000</value></property>
</bean>
<bean id="sessionFactory02"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource02" />
<property name="packagesToScan">
<list>
<value>com.cpframework.function.**.model.mysql</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.current_session_context_class">jta</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</prop>
</props>
</property>
</bean>
<!-- mysqlDAO -->
<bean id="hibernateDAO02" class="org.cpframework.dao.hibernate4.CP_Hibernate4DAOImpl">
<property name="sessionFactory" ref="sessionFactory02"></property>
</bean>
<!-- atomikos事务管理器 -->
<bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
init-method="init" destroy-method="close">
<description>UserTransactionManager</description>
<property name="forceShutdown">
<value>true</value>
</property>
</bean>
<bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
<property name="transactionTimeout" value="300" />
</bean>
<!-- spring 事务管理器 -->
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="atomikosTransactionManager"/>
<property name="userTransaction" ref="atomikosUserTransaction" />
<property name="allowCustomIsolationLevels" value="true"/>
</bean>
<aop:config proxy-target-class="true">
<aop:pointcut id="servicePoint"
expression="execution (* com.cpframework.function.*.service.*.*Service*.*(..))" />
<aop:advisor pointcut-ref="servicePoint" id="txAdvisor"
advice-ref="defaultTxAdvice" />
</aop:config>
<tx:advice id="defaultTxAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="find*" read-only="true" />
<tx:method name="get*" read-only="true" />
<tx:method name="query*" read-only="true" />
<tx:method name="load*" read-only="true" />
<tx:method name="add*" propagation="REQUIRED" rollback-for="java.lang.Exception" />
<tx:method name="create*" propagation="REQUIRED"
rollback-for="java.lang.Exception" />
<tx:method name="save*" propagation="REQUIRED"
rollback-for="java.lang.Exception" />
<tx:method name="update*" propagation="REQUIRED"
rollback-for="java.lang.Exception" />
<tx:method name="modify*" propagation="REQUIRED"
rollback-for="java.lang.Exception" />
<tx:method name="delete*" propagation="REQUIRED"
rollback-for="java.lang.Exception" />
<tx:method name="remove*" propagation="REQUIRED"
rollback-for="java.lang.Exception" />
<tx:method name="apply*" propagation="REQUIRED"
rollback-for="java.lang.Exception" />
<tx:method name="handle*" propagation="REQUIRED"
rollback-for="java.lang.Exception" />
<tx:method name="do*" propagation="REQUIRED"
rollback-for="java.lang.Exception" />
</tx:attributes>
</tx:advice>
三.transactions.properties
将transactions.properties文件放到编译根路径下,可根据需要开启相关注解,参见附件。
需要注意两点:
1.session必须使用sessionFactory.openSession()的方式获得,不能使用sessionFactory.getCurrentSession()。
2.更新操作必须调用session.flush()方法。
例如:
public void update(Object entity) {
Session session = sessionFactory.openSession();
session.update(entity);
session.flush();
}