spring + ibatis + jta分布式事务管理,只读事务失败

rascalboy520 2010-10-21 06:23:03
datasource.xml

<!-- ================================== 配置数据源 ================================== -->
<!-- 数据源A -->
<bean id="dataSourceA" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
<property name="uniqueResourceName" value="mysql/test"/>
<property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"/>
<property name="xaProperties">
<props>
<prop key="user">${jdbc.username}</prop>
<prop key="password">${jdbc.password}</prop>
<prop key="URL">${jdbc.url_test1}</prop>
</props>
</property>
<property name="poolSize" value="3" />
</bean>

<!-- 数据源B -->
<bean id="dataSourceB" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
<property name="uniqueResourceName" value="mysql/test2"/>
<property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"/>
<property name="xaProperties">
<props>
<prop key="user">${jdbc.username}</prop>
<prop key="password">${jdbc.password}</prop>
<prop key="URL">${jdbc.url_test2}</prop>
</props>
</property>
<property name="poolSize" value="3" />
</bean>

<!-- ================================== 配置ibatis ============================== -->
<bean id="sqlMapClientA" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="dataSource">
<ref local="dataSourceA" />
</property>
<property name="configLocation">
<value>classpath:sqlmap/SqlMapConfig-a.xml</value>
</property>
</bean>
<bean id="sqlMapClientB" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="dataSource">
<ref local="dataSourceB" />
</property>
<property name="configLocation">
<value>classpath:sqlmap/SqlMapConfig-b.xml</value>
</property>
</bean>

<bean id="daoTargetA" abstract="true">
<property name="sqlMapClient" ref="sqlMapClientA" />
</bean>

<bean id="daoTargetB" abstract="true">
<property name="sqlMapClient" ref="sqlMapClientB" />
</bean>


jta.xml

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

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

<bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="atomikosTransactionManager" />
<property name="userTransaction" ref="atomikosUserTransaction" />
<property name="allowCustomIsolationLevels" value="true"/>
</bean>

<!-- aop配置 -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="get*" propagation="REQUIRED" read-only="true"/>
<tx:method name="load*" propagation="REQUIRED" read-only="true"/>
<tx:method name="list*" propagation="REQUIRED" read-only="true"/>
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>

<!-- 事务切面配置 -->
<aop:config>
<aop:pointcut id="serviceOperation" expression="execution(* com.dtb.test.service.impl..*.*(..))" />
<aop:advisor pointcut-ref="serviceOperation" advice-ref="txAdvice" />
</aop:config>


当出现异常时,可以正常回滚,但对于只读事务,没有拦截,操作成功

测试代码:

@Controller("tabAService")
public class TabAServiceImpl implements TabAService {

@Autowired
private TabADao tabADao;

@Autowired
private TabBDao tabBDao;

@Override
public int add(TabA tabA) {
return tabADao.add(tabA);
}

@Override
public TabA get(int id) {
tabBDao.add(new TabB());
tabADao.add(new TabA());
return tabADao.get(1);
}

@Override
public TabA getTabA(int Id) {
tabBDao.add(new TabB());//添加入库方法,如果是只读事务,这里会回滚
tabADao.add(new TabA());//添加入库方法,如果是只读事务,这里会回滚
return tabADao.get(1);
}

}


麻烦有经验的朋友帮看一下,先谢过!
...全文
820 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
盛夏MARS 2013-06-25
  • 打赏
  • 举报
回复
LZ,也是跨库事务吧,我现在也在弄这一块问题很多啊,我没细配readonly之类的方法拦截,我只是在业务方法入口上放了注解:@Transactional(readOnly=true) 或 @Transactional(readOnly = false, rollbackFor = Exception.class),atomikos针对多个更新操作会加入XAResource,最后根据Resource一个一个commit,其中出现异常即回滚.
wei19820509 2012-02-07
  • 打赏
  • 举报
回复
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
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/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
default-lazy-init="true" default-autowire="byName">

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>classpath:db.properties</value>
</property>
</bean>
<!-- Spring 2.5 提供的AutoWired功能 -->
<!-- 该 BeanPostProcessor 将自动起作用,对标注 @Autowired 的 Bean 进行自动注入 -->
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
<context:component-scan base-package="com.umessage" />

<!-- 配置事务管理器 -->
<!--
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref local="dataSource" />
</property>
</bean>
-->
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager">
<ref bean="atomikosTransactionManager" />
</property>
<property name="userTransaction">
<ref bean="atomikosUserTransaction" />
</property>
<property name="allowCustomIsolationLevels" value="true"/>
</bean>

<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" propagation="NOT_SUPPORTED" read-only="true" />
<tx:method name="query*" propagation="NOT_SUPPORTED" read-only="true" />
<tx:method name="find*" propagation="NOT_SUPPORTED" read-only="true" />
<tx:method name="select*" propagation="NOT_SUPPORTED" read-only="true" />
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>

<!-- 配置那些类的方法进行事务管理,当前包中的子包、类中所有方法需要,还需要参考tx:advice的设置 -->
<aop:config>
<aop:pointcut id="allManagerMethod"
expression="execution (* com.umessage.ticket.service.*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod" />
</aop:config>

<!-- 配置数据源 -->
<bean id="datasource1" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
<property name="uniqueResourceName">
<value>oracle/readp</value>
</property>
<property name="xaDataSourceClassName">
<value>${jdbcr.className}</value>
</property>
<property name="xaProperties">
<props>
<prop key="user">${jdbcr.user}</prop>
<prop key="password">${jdbcr.password}</prop>
<prop key="URL">${jdbcr.driverUrl}</prop>
</props>
</property>
<property name="maxPoolSize"><value>10</value></property>
<property name="minPoolSize"><value>2</value></property>
<property name="loginTimeout"><value>30</value></property>
<property name="reapTimeout"><value>20000</value></property>
<!-- set a SQL for testing connection -->
<property name="testQuery">
<value>select 1 from dual</value>
</property>
</bean>

<bean id="datasource2" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
<property name="uniqueResourceName">
<value>oracle/writep</value>
</property>
<property name="xaDataSourceClassName">
<value>${jdbcw.className}</value>
</property>
<property name="xaProperties">
<props>
<prop key="user">${jdbcw.user}</prop>
<prop key="password">${jdbcw.password}</prop>
<prop key="URL">${jdbcw.driverUrl}</prop>
</props>
</property>
<property name="maxPoolSize"><value>10</value></property>
<property name="minPoolSize"><value>2</value></property>
<property name="loginTimeout"><value>30</value></property>
<property name="reapTimeout"><value>20000</value></property>
<!-- set a SQL for testing connection -->
<property name="testQuery">
<value>select 1 from dual</value>
</property>
</bean>


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

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


<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation" value="classpath:sqlMapConfig.xml"></property>
<property name="dataSource" ref="datasource1" />
</bean>
<bean id="sqlMapClient2" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation" value="classpath:sqlMapConfig.xml"></property>
<property name="dataSource" ref="datasource2" />
</bean>

<bean id="sqlMapClientMap" class="com.umessage.framework.dynamicds.SqlMapClientMap">
<property name="map">
<map key-type="java.lang.String">
<entry key="productRead" value-ref="sqlMapClient" />
<entry key="productWrite" value-ref="sqlMapClient2" />
</map>
</property>
</bean>

</beans>
handingbiao 2011-05-03
  • 打赏
  • 举报
回复
请问一下,楼主有解决方案了吗?
有的话,请帮忙发我一份dingbiao_han@longtopgs.com
LCKKING 2010-11-19
  • 打赏
  • 举报
回复
你这个问题我也碰到过
你可以看看
http://www.javaeye.com/topic/319768
http://www.javaeye.com/wiki/problem/10624
zwh5067177 2010-11-19
  • 打赏
  • 举报
回复
添人气。
gloryl 2010-11-17
  • 打赏
  • 举报
回复
楼主的问题解决了没?
怎么解决的?到底是什么原因引起的?

我也碰到类似的问题了,
如果事务过程中发生异常,也能正常回滚,
只是配置只读事务的时候却能够执行更新操作。

rascalboy520 2010-11-03
  • 打赏
  • 举报
回复
此帖不沉.................求解.............
rascalboy520 2010-11-01
  • 打赏
  • 举报
回复
回复18楼:
是的,我用了注解,这样做可以减少大量的配置文件处理
xuyang840117 2010-10-29
  • 打赏
  • 举报
回复
楼主 你还在吗?

顶下
xuyang840117 2010-10-27
  • 打赏
  • 举报
回复
<bean id="tabAService" class="com.dtb.test.service.impl.TabAServiceImpl "> 
<property name="daoTargetA" ref="daoTargetA"></property>
<property name="daoTargetB" ref="daoTargetB"></property>
</bean>
xuyang840117 2010-10-27
  • 打赏
  • 举报
回复
先帮你顶下
请教你下哈

你在TabAServiceImpl 类中 注入了
就不用在xml 配置

<bean id="tabAService" class="com.dtb.test.service.impl.TabAServiceImpl "> <property name="daoTargetA" ref="daoTargetA"></property>
<property name="daoTargetB" ref="daoTargetB"></property> </bean>

了吗?
feixiaocaohen 2010-10-22
  • 打赏
  • 举报
回复
太复杂了,帮你顶下吧,加油,开心每一天
Landor2004 2010-10-22
  • 打赏
  • 举报
回复
楼主可以自己用jdbc方式直接设置一下试试,有的驱动是没有实现readonly的,虽然设置了,但是不一定成功的

也许只是一个简单的“自动提交”的操作
rascalboy520 2010-10-22
  • 打赏
  • 举报
回复
就像是配置单数据源那样的
rascalboy520 2010-10-22
  • 打赏
  • 举报
回复
恩,这些我之前都有试过,没有效果的
包括使用注解方式,同样都不行,
所以问题应该还是在配置上面,
但在网上找到的资源,也有和我的配置一样的,但他们都没有提到只读的效果
只是针对数据库异常作为重点,
我是想两个都要实现
jypapgl 2010-10-22
  • 打赏
  • 举报
回复

<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="del*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="*" read-only="true"/>


没看出来啥

反过来试一下呢
rascalboy520 2010-10-22
  • 打赏
  • 举报
回复
10楼的走远点,日
rascalboy520 2010-10-22
  • 打赏
  • 举报
回复
感觉是datasource与txManager没有"联系"上,
找了好久没有找到他们两个是怎样扯上关系的,

但是发生异常时,数据又能正常进行回滚,仅这一点,应该足以证明他们是已经对应上了
所以我帮越来越木,找不到原因出在哪,

这种应用,应该有人配置过,所以发出来,想让配置过这种应用的朋友,指点一下
xuyang840117 2010-10-22
  • 打赏
  • 举报
回复
不好意思 没看仔细
你写的 expression="execution(* com.dtb.test.service.impl..*.*(..))"
xuyang840117 2010-10-22
  • 打赏
  • 举报
回复
是这样吗?
开启的应该在dao层吧?
加载更多回复(4)

50,526

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧