您的位置:首页 > 编程语言 > Java开发

mybatis+spring 事务管理

2015-11-27 09:24 531 查看
公司用的spring+mybatis的框架,但没有配置事务管理,自己花了一些时间尝试配置的事务,记录下配置流程及中间出现的问题.
application-contex.xml配置:基本配置大同小异,按照这个配置就可以,需要修改的地方就是自己的数据库配置,事务在service层的配置
<importresource="ApplicationContext-service.xml"/>
<!--  -->

<beanid="dataSource"
class="com.mchange.v2.c3p0.ComboPooledDataSource"destroy-method="close"> 
<propertyname="driverClass"value="oracle.jdbc.driver.OracleDriver"/>

<propertyname="jdbcUrl"value="jdbc:oracle:thin:@12.23.22.43:9801:orcl"/>
<propertyname="user"value="o2o"/>
<propertyname="password"value="password"/> 

<propertyname="acquireIncrement"value="5"></property>
 
<propertyname="acquireRetryDelay"value="1000"></property>
    <propertyname="acquireRetryAttempts"value="60"></property>
 
    <propertyname="initialPoolSize"value="3"></property>
 
    <propertyname="maxPoolSize"value="50"></property>
 
    <propertyname="minPoolSize"value="1"></property>
 
    <propertyname="idleConnectionTestPeriod"value="10"/>
    <propertyname="maxIdleTime"value="0"/>
    <propertyname="breakAfterAcquireFailure"value="false"></property>
</bean>
<beanid="sqlSessionFactory"class="org.mybatis.spring.SqlSessionFactoryBean">
<propertyname="dataSource"ref="dataSource"/>
<propertyname="configLocation"value="classpath:cfg/mybatis/config.xml"/>
<!-- 这个地方下面解释<property name="transactionFactory">
  <bean class="org.apache.ibatis.transaction.managed.ManagedTransactionFactory" />
</property>   -->
</bean>

<beanid="sqlSession"class="org.mybatis.spring.SqlSessionTemplate">
<constructor-argindex="0"ref="sqlSessionFactory"></constructor-arg>
</bean>

<!-- =============================事务相关控制================================ -->
<!-- 由spring管理mybatis的事物 -->
<beanid="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<propertyname="
dcb1
dataSource"ref="dataSource"></property>
</bean>
<!-- 定义拦截器,用来指定事物属性,级别,和异常处理 -->
<tx:adviceid="txAdvice"transaction-manager="transactionManager">
<tx:attributes>
<tx:methodname="delete*"propagation="REQUIRED"read-only="false"
rollback-for="java.lang.Exception"/>
<tx:methodname="insert*"propagation="REQUIRED"read-only="false"
rollback-for="java.lang.Exception"/>
<tx:methodname="update*"propagation="REQUIRED"read-only="false"
rollback-for="java.lang.Exception"/>
<tx:methodname="save*"propagation="REQUIRED"read-only="false"
rollback-for="java.lang.Exception"/>
<tx:methodname="*"propagation="REQUIRED"read-only="true"/>
</tx:attributes>
</tx:advice>
<!--切面配置  -->
<aop:config>
<!--把事务控制在Service层,可配置多个-->
<aop:pointcutid="transactionServicePointCut"
expression="execution(* msun.server.service..*(..))"/>
<aop:advisoradvice-ref="txAdvice"pointcut-ref="transactionServicePointCut"/>
</aop:config>
2,基本的配置配好了,但我在测试事务的时候出现了两个问题:
1.
 org.springframework.dao.TransientDataAccessResourceException: SqlSessionFactory must be using a SpringManagedTransactionFactory in order to use Spring transaction synchronization
--这个错误搜索了下,终于在一个英文网站上发现了老外跟我一样的错误,原因是上面:
property name="transactionFactory">
  <bean class="org.apache.ibatis.transaction.managed.ManagedTransactionFactory" />
</property> 没有注释掉,具体原因没有深究.
2.配置好了以后,发现还是不行,事务还是没有执行,原因是不能在service中添加try catch异常,否则spring无法判断方法是否执行成功.
3.网上别人整理的一些问题:
第一种情况:

Spring MVC 和 Spring 整合的时候,SpringMVC的springmvc.xml文件中 配置扫描包,不要包含 service的注解,Spring的applicationContext.xml文件中 配置扫描包时,不要包含controller的注解,如下所示:


SpringMVC的xml配置:


<span style="font-size:10px;"><strong><context:component-scan base-package="com.insigma">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
</context:component-scan></strong></span>


Spring MVC启动时的配置文件,包含组件扫描、url映射以及设置freemarker参数,让spring不扫描带有@Service注解的类。为什么要这样设置?因为springmvc.xml与applicationContext.xml不是同时加载,如果不进行这样的设置,那么,spring就会将所有带@Service注解的类都扫描到容器中,等到加载applicationContext.xml的时候,会因为容器已经存在Service类,使得cglib将不对Service进行代理,直接导致的结果就是在applicationContext 中的事务配置不起作用,发生异常时,无法对数据进行回滚。以上就是原因所在。

同样的在Spring的xml配置如下:

<span style="font-size:10px;"><strong><context:component-scan base-package="com.insigma">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan></strong></span>


扫描包路径,不扫描带有@Controller注解的类。因为这些类已经随容器启动时,在springmvc.xml中扫描过一遍了。

完成以上工作,我的Spring就支持事务回滚了。OK

第二种情况:使用了MySQL数据库,如果用mysql数据库,数据库表你如果是自动建表,那么就需要把建表的Engine设置为InnoDB格式,自动建表的格式为:MyISAM,这中格式的是不支持事务管理的。 

第三种情况:在测试代码中,一定要在catch块中抛出 异常 ,以便Spring事务能发现异常。

借鉴:
http://blog.csdn.net/walkerjong/article/details/7839002


http://www.iteye.com/topic/1123069
http://blog.sina.com.cn/s/blog_7deb4bd60101cnuf.html
http://blog.sina.com.cn/s/blog_5ddc071f0100uf7x.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring mybatis 事务 无效