springboot service 事物回滚的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
strongme
V2EX    Java

springboot service 事物回滚的问题

  •  
  •   strongme
    strongme 2017-11-22 13:43:01 +08:00 7824 次点击
    这是一个创建于 2880 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在有如下代码: https://gitee.com/strongme/codes/g0157y3zxhmn2bfurwvtc22 save 方法中某个位置抛出异常,整个事务没有回滚。这是什么问题呢?

    第 1 条附言    2017-11-22 15:29:29 +08:00
    https://gitee.com/strongme/basic-springboot
    代码我传这里了,可以下下来看看,就是 UserService 里面所有事务都不起作用
    第 2 条附言    2017-11-23 09:36:07 +08:00
    我单独把 user 的 save 方法放到一个新的 Service,事务是正常的!
    然而原来那个 UserSerivce 里面的需要事务的内容,还是不行!
    要哭
    第 3 条附言    2017-11-23 14:37:34 +08:00
    已经解决了,谢谢各位,具体解决办法见仓库。
    是 shiro 的问题
    22 条回复    2017-11-29 09:15:01 +08:00
    neoblackcap
        1
    neoblackcap  
       2017-11-22 14:34:54 +08:00
    抛 ServiceException,但是没有回滚?
    JRay
        2
    JRay  
       2017-11-22 15:09:56 +08:00
    不是应该抛出去嘛。。
    strongme
        3
    strongme  
    OP
       2017-11-22 15:29:58 +08:00
    @neoblackcap 朋友可以下下来工程跑跑试试,我要难受~~
    weics
        4
    weics  
       2017-11-22 16:34:12 +08:00
    看下 ServiceException 继承的是 check 异常还是 uncheck 异常,顺便把 save 方法上面的 Transactional 去除,只保留 service 上面的注解
    strongme
        5
    strongme  
    OP
       2017-11-22 16:43:24 +08:00
    @weics 朋友你说的这两个我都试过了,但是还是不行
    weics
        6
    weics  
       2017-11-22 16:49:40 +08:00
    @strongme
    数据库的引擎是否支持代码回滚?
    strongme
        7
    strongme  
    OP
       2017-11-22 16:55:21 +08:00
    @weics 是支持的,别的 Service 没问题,就是 UserService
    hustlike
        8
    hustlike  
       2017-11-22 16:58:27 +08:00
    你是不是要配置一个 transactionManager 的 bean ?
    weics
        9
    weics  
       2017-11-22 17:01:21 +08:00
    @strongme
    在别的 service 里面注入 user 的 dao 层,然后试试添加操作,看别的 service 能不能回滚,定位一下
    tr0uble
        10
    tr0uble  
       2017-11-22 17:14:48 +08:00
    看下 UserService 是不是一个代理类,回滚你明确指定了 ServiceException,是否有这种异常抛出
    strongme
        11
    strongme  
    OP
       2017-11-22 17:56:14 +08:00
    @tr0uble 我先查查什么叫代理类~~
    strongme
        12
    strongme  
    OP
       2017-11-22 17:58:56 +08:00
    @tr0uble 应该算是代理类
    关键是其他的都正常
    就这个 UserService 不正常
    lsyhyp
        13
    lsyhyp  
       2017-11-22 18:07:40 +08:00
    贴一下异常栈?
    seaswalker     14
    seaswalker  
       2017-11-23 07:40:03 +08:00 via iPhone
    从哪里调的这个方法
    strongme
        15
    strongme  
    OP
       2017-11-23 09:12:05 +08:00
    @hustlike 有事务的 Service 有好多个呢,但是唯独这个 UserService 不起作用,有时间的话可以看看我传的那个代码~~好心塞
    strongme
        16
    strongme  
    OP
       2017-11-23 09:12:25 +08:00
    @weics 好办法!我去试试
    strongme
        17
    strongme  
    OP
       2017-11-23 09:14:21 +08:00
    @lsyhyp 朋友这到不是异常的问题,是事务的问题呢,异常是我手动故意抛出来的,要是测试事务回滚问题
    strongme
        18
    strongme  
    OP
       2017-11-23 09:15:17 +08:00
    @seaswalker 朋友是在 Controller 里面调用呢
    kaka8wp
        19
    kaka8wp  
       2017-11-23 09:44:43 +08:00
    在 springBoot 使用事物时,发现事务并没有正常执行,没有进行回滚。
    [java] view plain copy
    @GetMapping("add")
    @ResponseBody
    @Transactional
    public void add(String companyName,String name){
    companyDao.add(companyName);
    try {
    userDao.addUser(name);
    }catch (DuplicateKeyException e){//这里在数据库将 name 设置成 unique key
    logger.error("添加失败。姓名:[ {} ],已存在",name);
    return new MyException("添加失败,名字已存在");//自定义异常 继承 Exception
    }
    }


    上述姓名重复时发现,公司名称依然添加成功,并没有进行回滚操作。

    分析:默认 spring 事务只在发生未被捕获的 RuntimeException 时才回滚。
    spring aop 异常捕获原理:被拦截的方法需显式抛出异常,并不能经任何处理,这样 aop 代理才能捕获到方法的异常,才能进行回滚,默认情况下 aop 只捕获 RuntimeException 的异常,但可以通过配置来捕获特定的异常并回滚
    换句话说在 service 的方法中不使用 try catch 或者在 catch 中最后加上 throw new runtimeexcetpion (),这样程序异常时才能被 aop 捕获进而回滚
    解决办法:
    1.首先确认数据库支持事务。即为 InnoDB。
    方案一:手动回滚。给注解加上参数如:@Transactional(rollbackFor=Exception.class)
    方案二:如上述分析。MyException 改为继承 RuntimeException 的异常。并且在 service 上层要继续捕获这个异常并处理
    方案三:在 service 层方法的 catch 语句中增加:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();语句,手动回滚,这样上层就无需去处理异常

    链接: http://blog.csdn.net/bestlovelymin/article/details/74942932
    strongme
        20
    strongme  
    OP
       2017-11-23 14:37:07 +08:00
    @kaka8wp 朋友我解决了,是 shiro 的问题,具体可以去仓库看看代码,是使用配置的问题,天生的
    jack80342
        21
    jack80342  
       2017-11-28 23:10:08 +08:00
    最近翻译了 Spring Boot 最新的官方文档,欢迎 Fork,https://www.gitbook.com/book/jack80342/spring-boot/details
    johnniang
        22
    johnniang  
       2017-11-29 09:15:01 +08:00 via Android
    @kaka8wp 注解 @Transactional 能在 Controller 方法上加?你确定开服务器后能访问到这个 add?
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2559 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 05:01 PVG 13:01 LAX 22:01 JFK 01:01
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86