• 0046 @Transactional注解的几个参数--事务传播控制--事务隔离级别--异常与回滚


    @Transactianal注解有一些属性,见Spring-Framework-Reference Table17.3 Transactional-settings

    @Transactional(propagation=Propagation.REQUIRED)           //控制事务传播。默认是Propagation.REQUIRED
    @Transactional(isolation=Isolation.DEFAULT)                //控制事务隔离级别。默认跟数据库的默认隔离级别相同
    @Transactional(readOnly=false)                             //控制事务可读写还是只可读。默认可读写
    @Transactional(timeout=30)                                 //控制事务的超时时间,单位秒。默认跟数据库的事务控制系统相同,又说是30秒
    @Transactional(rollbackFor=RuntimeException.class)         //控制事务遇到哪些异常才会回滚。默认是RuntimeException
    @Transactional(rollbackForClassName=RuntimeException)      //同上
    @Transactional(noRollbackFor=NullPointerException.class)   //控制事务遇到哪些异常不会回滚。默认遇到非RuntimeException不会回滚
    @Transactional(noRollbackForClassName=NullPointerException)//同上
    

    控制事务传播----propagation属性

    事务的传播是指:
        A.f1()有事务X
        B.f2()有事务Y
        当A.f1()调用B.f2()的时候,B.f2()中的代码执行哪个事务

    该属性可能的值有(以下属性值加在B.f2()上来理解):

    Propagation.NEVER:
        B.f2()不能在任何事务下执行,如果A.f1()调用它,那么抛异常。绝不接受,硬给就拼命

    Propagation.NOT_SUPPORTED:
        B.f2()不需要在事务中执行。如果被需要事务X的A.f1()调用,那么事务X被挂起,B.f2()执行完毕X才恢复。不接受,硬给也不收

    Propagation.REQUIRES_NEW:
        如果A.f1()调用B.f2(),那么事务X被挂起,重新创建一个事务Y,B.f2()在事务Y中执行,Y执行完毕再继续X事务。接受,给的不收,用自己的

    Propagation.SUPPORTS:
        如果B.f2()被A.f1()调用,那么执行X事务;如果被没有事务的方法调用,那么就在没有事务的环境下执行。接受,给就收下,不给也不要

    Propagation.REQUIRED:
        如果A.f1()调用B.f2(),那么B.f2()在事务X中执行;如果B.f2()没有被调用,那就执行自己的事务Y。接受,给就收下,不给就用自己的

    Propagation.MANDATORY:
        B.f2()不能开启自己的事务,只能被开启了事务的A.f1()调用,如果被没有开启事务其他的方法调用,则抛异常。自己没有,给,必须给,不给就哭

    Propagation.NESTED:
        看不懂

    控制事务隔离级别----属性isolation

    事务隔离级别是数据库的概念,在多个事务对一批记录进行操作的时候,可能出现各种冲突的情况

    该属性的可能值有:
    Isolation.READ_UNCOMMITED
        读未提交
        可以读到其他事务未提交的数据。导致脏读(dirty read)

    Isolation.READ_COMMITED
        读已提交。这是很多数据库的默认隔离级别,但不是MySQL的。
        不能读到其他事务未提交的数据,只能读到已提交的数据。解决了脏读,可导致重读幻读
        重读:在预读之后,commit之前,其他事务更新了数据,导致两次读到的数据不相同
        幻读:在预读之后,commit之前,其他事务插入数据,导致两次读到的数据条数不相同

    Isolation.REPEATABLE_READ
        可重复读。这是MySQL的默认事务隔离级别
        解决了脏读,重读,但依然存在幻读问题。

    Isolation.SERIALIZABLE
        可串行化
        最高的事务隔离级别。解决了脏读、重读、幻读
        但导致大量的超时和锁竞争。

    Isolation.DEFAULT
        数据库默认隔离级别

    只可读/可读写

    有的事务不涉及到写操作,就可以将其指定为只读事务:@Transactional(readOnly=true),这样可以节约一些资源开销
    默认是可读写

    遇到哪些异常会回滚和不回滚----rollbackFor和noRollbackFor属性

    默认在遇到RuntimeException的时候会回滚。

    如果要指定在遇到checkedException的时候也回滚
        @Transactional(rollbackFor={IOException.class,FileNoteFoundException})
        多个异常类型,用数组

    如果要指定遇到几个RuntimeException的时候不回滚
        @Transactional(noRollbackFor={NullPointerException.class,IndexOutOfBoundsException.class})
        多个异常类型,用数组
        测试的时候,抛出了Transaction rolled back because it has been marked as rollback-only,暂不知道原因


    其他:
    @Transaction应当添加在具体的实现类而不是接口上

  • 相关阅读:
    ListView -————不能不说的秘密
    良好的开端是成功的第一步———构建程序
    你所不知道的windows窗体
    数据库查询终结版2———分组——连接
    数据库的终结版查询————你想知道吗?
    《官神》浏览闲看笔记
    坚信梦想,奋勇前进!____OS小题狂刷2333
    众里寻他千百度,蓦然回首,却见写者优先算法,她在书本寂静处!
    生产消费问题扩展——三个并发进程R,M,P和一个共享的循环缓冲区B的并发控制
    多生产者-多消费者-环形缓冲区问题
  • 原文地址:https://www.cnblogs.com/sonng/p/6591319.html
Copyright © 2020-2023  润新知