美文网首页
@Transational注解的基本介绍和使用

@Transational注解的基本介绍和使用

作者: kacen | 来源:发表于2020-09-14 23:32 被阅读0次

我是kacen,一个会点前端的java后端开发工程师。

前言

 项目中在对事务进行操作的时候被要求做@Transational注解,why?

 当我们对事务进行操作时,在做多个事务的时候就会要求数据一致性,但是如果在进行多个事务操作的时候往往会有事务失败的时候,但是事务A失败,事务B成功,那就会导致一系列的数据不一致的问题。异常的分类有什么呢,看下图: Exception.png
这里我们又分了运行时异常(RuntimeException)和非运行时异常,具体请自己百度一下都有哪些。
这里面又分了我们常说的可检查型异常和不可检查型异常:

可检查型异常:!(RuntimeException extend Exception)
不可检查型异常:Error & RuntimeException & SonClass extends RuntimeException

运行时异常:

 出现运行时异常时,常常会导致线程中止或者主线程终止,如果想要程序正常运行就需要捕获所有的运行时异常,这样才可以避免程序终止。

非运行时异常:

 这类异常我感觉大家其实都不陌生,因为java编译器会强制要求我们try&catch来处理异常代码,不然连编译都不给你过。

正文

 1.首先我们先来讲一下@Transational注解的位置,它的话可以在协议层注释,或者在dao层,主要看项目中的具体需求来写。
 2.单独写@Transational的注释会有什么问题呢?Spring的事务框架的默认是在运行时异常或者在不可查异常时才进行事务回滚。这里贴一下源代码:
RuleBasedTransactionAttribute继承的DefaultTransactionAttribute

public class RuleBasedTransactionAttribute 
    extends DefaultTransactionAttribute 
    implements Serializable {

    ...
    
    @Override
    public boolean rollbackOn(Throwable ex) {
        if (logger.isTraceEnabled()) {
            logger.trace("Applying rules to determine whether transaction should rollback on " + ex);
        }

        RollbackRuleAttribute winner = null;
        int deepest = Integer.MAX_VALUE;

        if (this.rollbackRules != null) {
            for (RollbackRuleAttribute rule : this.rollbackRules) {
                int depth = rule.getDepth(ex);
                if (depth >= 0 && depth < deepest) {
                    deepest = depth;
                    winner = rule;
                }
            }
        }

        if (logger.isTraceEnabled()) {
            logger.trace("Winning rollback rule is: " + winner);
        }

        // User superclass behavior (rollback on unchecked) if no rule matches.
        //无配置时 进入了这里了 找爹看看怎么操作
        if (winner == null) {
            logger.trace("No relevant rollback rule found: applying default rules");
            return super.rollbackOn(ex);
        }

        return !(winner instanceof NoRollbackRuleAttribute);
    }
    
    ...
}

然后咋们看一下父类DefaultTransactionAttribute,简单粗暴无理由

public class DefaultTransactionAttribute extends DefaultTransactionDefinition implements TransactionAttribute {
    ...
    @Override
    public boolean rollbackOn(Throwable ex) {
        return (ex instanceof RuntimeException || ex instanceof Error);
    }
    ...
    
}

看完源码大家是不是豁然开朗,哈哈哈。

然后我们来看下它的使用吧

让checked例外也回滚:在整个方法前加上 @Transactional(rollbackFor=Exception.class)
让unchecked例外不回滚:@Transactional(notRollbackFor=RunTimeException.class)
不需要事务管理的(只查询的)方法:@Transactional(propagation=Propagation.NOT_SUPPORTED
如果对异常比较了解的可以写异常的派生类,这样显得你牛逼。罒ω罒
这里有一个需要注意的问题,如果使用了该注释,try catch块使用时小心,直接给throw出来,不然被捕获了就不回滚了哦!!

以下是spring团队对该注释的建议(给你们翻译了)

因为注解是不能继承的,这就意味着如果你正在使用基于类的代理时,那么事务的设置将不能被基于类的代理所识别,而且对象也将不会被事务代理所包装(将被确认为严重的)。因此,请接受Spring团队的建议并且在具体的类上使用 @Transactional 注解。
@Transactional 注解标识的方法,处理过程尽量的简单。尤其是带锁的事务方法,能不放在事务里面的最好不要放在事务里面。可以将常规的数据库查询操作放在事务前面进行,而事务内进行增、删、改、加锁查询等操作。

以上就是对@Transational注解的基本了解和使用啦,有什么建议或者讨论什么问题的可以@我哦。

相关文章

网友评论

      本文标题:@Transational注解的基本介绍和使用

      本文链接:https://www.haomeiwen.com/subject/jpktyktx.html