开发者社区> 问答> 正文

JAVA Spring + Mybatis如何控制事务在service层 : 配置报错 

问题如题,本人使用的是spring tx+aop,配置控制到了services层,配置如下:
<tx:advice id="yqTxAdvice" transaction-manager="transactionManager">   <tx:attributes>    <tx:method name="delete*" propagation="REQUIRED" read-only="false"     rollback-for="java.lang.Exception" no-rollback-for="java.lang.RuntimeException" />    <tx:method name="insert*" propagation="REQUIRED" read-only="false"     rollback-for="java.lang.Exception" />    <tx:method name="update*" propagation="REQUIRED" read-only="false"     rollback-for="java.lang.Exception" />    <tx:method name="find*" propagation="SUPPORTS" />    <tx:method name="get*" propagation="SUPPORTS" />    <tx:method name="select*" propagation="SUPPORTS" />    <tx:method name="query*" propagation="SUPPORTS" />   </tx:attributes>  </tx:advice>
<aop:config>   <aop:pointcut id="pc"    expression="execution(* com.yinqing.mosweb.serivices..(..))" /> <!--把事务控制在Service层 -->   <aop:advisor pointcut-ref="pc" advice-ref="yqTxAdvice" />  </aop:config>
然后JAVA services中执行如下代码:
@Autowired  public CellInfoMapper cellInfoMapper;
private static void test() throws Exception{   throw new Exception();  }    public boolean insertBatch(List<CellInfoModel> cellInfoModels){   try{    Long before = System.currentTimeMillis();    cellInfoMapper.deleteAll();    test();    cellInfoMapper.insertBatch(cellInfoModels);    Long takeTime = System.currentTimeMillis()-before;    logger.info("data size :"+cellInfoModels.size()+" take time(millis)"+takeTime);    return true;   }catch(Exception e){    logger.info("批量插入小区信息数据错误!");    e.printStackTrace();    return false;   }  }
在如上代码中,可以明白,当执行delete方法后,抛出一个异常,然后才执行insertBatch方法,目的是模拟delete方法执行后,后续执行的代码中有异常抛出,此时需要rollback执行了删除的数据。但是发现,如此配置无效,无法将delete的数据rollback回来。
我希望的是一个service方法,不管调用了多少次mapper,都处于同一个事务中,services方法结束,才为一个完整的事务。
 
 
 

展开
收起
kun坤 2020-06-03 16:36:06 885 0
1 条回答
写回答
取消 提交回答
  • 我就知道openSessionInView ######这个是mybatis呢,与openSessionInView无关。。。###### 你insert方法中的异常未抛出,spring不知道发生了异常。 未抛出的原因是在catch中使用了return语句,导致异常无法抛出insert方法之外。 一般是绝对禁止在catch 和finally中使用return语句的。主要是会丢失掉抛出的异常。 ######回复 @Alfie : catch中的return语句去掉没有?异常抛不出去,问题是在这里。######亲,谢谢回答,首先学习了,spring配置不更改,JAVA方法修改为向上抛出异常,返回值改为void,但问题依旧,仍然无法rollback被deleteAll的数据。######spring是靠AOP的方法拦截异常去判断是否需要事务回滚或提交的。你自己把异常给catch了,又不往上抛出 别人怎么知道你的方法是否执行正常呢######亲,谢谢回答,学习了,现在JAVA方法修改后,是往上抛异常,但是在Action层有做异常处理,这个应该是没问题的。######应该是service层抛出异常######现在纠结的情况是,一个mapper方法是一个完整的事务!######你用的springmvc吗?mvc配置文件和app配置文件是分开写的吗?######不是用的springmvc,谢谢######版本不对,我试过只有spring和mybatis都用3.0.6版本才支持申明式事务,楼主可以换版本试一下。######spring 用的是3.1.1版本,mybatis 3.1.0版本######参见  http://kinglixing.blog.51cto.com/3421535/723870######catch 里不  return false; 直接 throw new Exception() ######<tx:method name="delete*" propagation="REQUIRED" read-only="false"

        rollback-for="java.lang.Exception" no-rollback-for="java.lang.RuntimeException" />
    它抛出的正是RuntimeException

    2020-06-05 13:24:19
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
云栖社区特邀专家徐雷Java Spring Boot开发实战系列课程(第20讲):经典面试题与阿里等名企内部招聘求职面试技巧 立即下载
微服务架构模式与原理Spring Cloud开发实战 立即下载
阿里特邀专家徐雷Java Spring Boot开发实战系列课程(第18讲):制作Java Docker镜像与推送到DockerHub和阿里云Docker仓库 立即下载