atomikos+jta+JdbcTemplate
依賴包(部分)
<!-- Spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.1.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>4.1.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>4.1.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>4.1.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </dependency> <dependency> <groupId>com.atomikos</groupId> <artifactId>transactions-jdbc</artifactId> <version>3.9.3</version> </dependency> <dependency> <groupId>javax.transaction</groupId> <artifactId>jta</artifactId> <version>1.1</version> </dependency>
<!--atomikos是分布式事務使用,jta是spring整合分布式事務使用 -->
事務等配置
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:jta.properties</value><!-- 修改默認配置使用 --> <value>classpath:jdbc.properties</value> <value>classpath:rpc.properties</value> <value>classpath:redis.properties</value> <value>classpath:servicesetting.properties</value> </list> </property> </bean> <!-- 數據源 --> <bean id="abstractDatasource" abstract="true" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close"> <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" /> <property name="poolSize" value="${datasource.poolSize}" /> <property name="minPoolSize" value="${datasource.minPoolSize}" /> <property name="maxPoolSize" value="${datasource.maxPoolSize}" /> <!--獲取連接失敗重新獲等待最大時間,在這個時間內如果有可用連接,將返回 --> <property name="borrowConnectionTimeout" value="60" /> <!--最大獲取數據時間,如果不設置這個值,Atomikos使用默認的5分鍾,那么在處理大批量數據讀取的時候,一旦超過5分鍾,就會拋出類似 Resultset is close 的錯誤. --> <property name="reapTimeout" value="20" /> <!--最大閑置時間,超過最小連接池連接的連接將將關閉 --> <property name="maxIdleTime" value="${datasource.maxIdleTime}" /> <!--連接回收時間 --> <property name="maintenanceInterval" value="60" /> <!--java數據庫連接池,最大可等待獲取datasouce的時間 --> <property name="loginTimeout" value="60" /> <property name="logWriter" value="60" /> <!-- <property name="maxLifetime" value="1800000"/> --> <property name="testQuery"> <value>select 1</value> </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 事務管理器,包裝了atomikos事務 --> <bean id="jtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> <property name="transactionManager"> <ref bean="atomikosTransactionManager" /> </property> <property name="userTransaction"> <ref bean="atomikosUserTransaction" /> </property> </bean> <!-- spring 事務模板,和spring的jta事務類似功能 --> <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"> <property name="transactionManager"> <ref bean="jtaTransactionManager" /> </property> </bean>
<!-- 聲明式事務使用 -->
<tx:annotation-driven transaction-manager="jtaTransactionManager" /> <bean id="dataSource0_navi_w_0" parent="abstractDatasource"> <property name="uniqueResourceName" value="mysql/navi_w_0" /> <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" /> <property name="xaProperties"> <props> <prop key="URL">${navi_w_0.url}</prop> <prop key="user">${navi_w_0.user}</prop> <prop key="password">${navi_w_0.password}</prop> <prop key="pinGlobalTxToPhysicalConnection">true</prop> <prop key="autoReconnect">true</prop> </props> </property> <property name="maxPoolSize" value="${c3p0_r.maxPoolSize}" /> </bean> <bean id="jdbcTemplate_navi_w_0" class="org.springframework.jdbc.core.JdbcTemplate"> <constructor-arg> <ref bean="dataSource0_navi_w_0" /> </constructor-arg> </bean>
jta.properties(修改默認配置使用)
com.atomikos.icatch.serial_jta_transactions=false com.atomikos.icatch.service=com.atomikos.icatch.standalone.UserTransactionServiceFactory com.atomikos.icatch.console_file_name = tm.out com.atomikos.icatch.log_base_name = tmlog com.atomikos.icatch.tm_unique_name = com.atomikos.spring.jdbc.tm com.atomikos.icatch.console_log_level = INFO com.atomikos.icatch.enable_logging=false com.atomikos.icatch.output_dir=./logs/atomikos_logs com.atomikos.icatch.log_base_dir=./logs/atomikos_logs
測試,JdbcTemplate操作數據庫
@Service public class TestService { @Resource(name = "jtaTransactionManager") private JtaTransactionManager jtaTransactionManager; @Resource private TestRpcDao testRpcDao; @Resource private Test2RpcDao test2RpcDao; @Resource(name = "transactionTemplate") private TransactionTemplate transactionTemplate; //編程式 public void test1() { UserTransaction userTx = jtaTransactionManager.getUserTransaction(); try { userTx.begin(); int i = test2RpcDao.testCinfInsert(); System.out.println("cinf:" + i); int j = testRpcDao.testNaviInsert(); System.out.println("navi:" + j); int a = 1 / 0; userTx.commit(); } catch (Exception e) { System.out.println("捕獲到異常,進行回滾" + e.getMessage()); e.printStackTrace(); try { userTx.rollback(); } catch (IllegalStateException e1) { System.out.println("IllegalStateException:" + e1.getMessage()); } catch (SecurityException e1) { System.out.println("SecurityException:" + e1.getMessage()); } catch (SystemException e1) { System.out.println("SystemException:" + e1.getMessage()); } } } //聲明式,不管用,網上方法:不去掃描Service層注解。嘗試了一下,然后解決了這個分布式事務問題。可以去掉@Service試下
@Transactional(rollbackFor={Exception.class, RuntimeException.class})
public String test2(){
int i = test2RpcDao.testCinfInsert();
System.out.println("cinf:" + i);
int j = testRpcDao.testNaviInsert();
System.out.println("navi:" + j);
// int a=1/0;
return null;
}
//事務模板方式
public void test3() {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
try {
int i = test2RpcDao.testCinfInsert();
System.out.println("cinf:" + i);
int j = testRpcDao.testNaviInsert();
System.out.println("navi:" + j);
int a = 1 / 0;
} catch (Exception ex) {
// 通過調用 TransactionStatus 對象的 setRollbackOnly() 方法來回滾事務。
status.setRollbackOnly();
ex.printStackTrace();
}
}
});
/*
* //有返回值的回調 Object obj=transactionTemplate.execute(new
* TransactionCallback(){
*
* @Override public Object doInTransaction(TransactionStatus status) {
*
* return 1; } });
*/
}
}
atomikos 配置好后 @transactional 注解不生效的問題 https://blog.csdn.net/u011696259/article/details/71603480
atomikos JTA/XA全局事務 http://www.tianshouzhi.com/api/tutorials/distributed_transaction/386
【分布式事務】使用atomikos+jta解決分布式事務問題 https://blog.csdn.net/kisscatforever/article/details/79129055