• 日常Bug排查-抛异常不回滚


    日常Bug排查-抛异常不回滚

    前言

    日常Bug排查系列都是一些简单Bug排查,笔者将在这里介绍一些排查Bug的简单技巧,同时顺便积累素材_

    Bug现场

    最近有人反映java应用操作数据库的时候,抛异常不回滚。这还了得,不过笔者笃定肯定是用法的锅,不然就全乱套了。所以笔者去Review他的代码。

    代码片段

    @Transacion(value="x") 
    public void s1() throw MyException{ 
    	update(1); 
    	throwBusinessException();
     	update(2); 
    } 
    

    乍看上去没啥问题。

    思路

    笔者用@Transaction注解也用了好几年了,从来没遇到过抛异常不回滚的情况。看他的用法也和笔者差不多呀?
    然后笔者稍微思索了会,发现我写的代码和出问题的这一段稍稍有些不一样。我是这么写的:

    @Transacion(value="transManager") 
    public void s1(){ 
    	update(1); 
     	update(2); 
    } 
    

    貌似我从来没有在函数上加过throw MyException,难道是这段有问题?
    翻看MyException代码,发现它仅仅继承了Exception。

    class MyEception extends Exception {
    }
    

    好像就这点不一样。而笔者自定义的Exception基本继承了RuntimeException的。

    翻下Spring源码

    按照这个思路,笔者去翻了下Spring的源码,看下它在声明式事务中的处理逻辑到底是什么,于是翻到了这一段处理事务异常的代码:

    TransactionAspectSupport.java
    protected void completeTransactionAfterThrowing(TransactionInfo txInfo, Throwable ex) {
    	if (txInfo.transactionAttribute.rollbackOn(ex)) {
    	}else{
    		// We don't roll back on this exception.
    		// Will still roll back if TransactionStatus.isRollbackOnly() is true.
    		// 在checkedException的时候,不会被rollBack,会commit!!!
    	}
    }
    @Override
    public boolean rollbackOn(Throwable ex) {
    	return (ex instanceof RuntimeException || ex instanceof Error);
    }
    

    看代码逻辑就明白了,只有异常继承RuntimeException或者Error的时候才会回滚!
    好了,让业务开发改了下代码,问题解决了。

    总结

    遇到问题时,找到出问题代码段和类似的正确代码段的不同处,以此为切入,往往能抓住线索。

  • 相关阅读:
    WebView自适应屏幕
    shell脚本:遍历删除
    查看Mysql执行计划
    Spring 源码学习(八) AOP 使用和实现原理
    Java:控制反转(IoC)与依赖注入(DI)
    浏览器-开发者工具
    查看kafka消息消费情况
    shell脚本:遍历删除文本内路径上文件
    聚簇索引与非聚簇索引(也叫二级索引)
    有关MySQL
  • 原文地址:https://www.cnblogs.com/alchemystar/p/14857783.html
Copyright © 2020-2023  润新知