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