美文网首页
Spring的声明式事务

Spring的声明式事务

作者: 赵镇 | 来源:发表于2017-08-30 08:22 被阅读90次

    Spring的声明式事务即使用@Transactional注解的方式来标明该方法需要事务支持。
    当使用Spring的事务管理的时候,需要特别注意的是@Transactional注解来自org.springframework.transaction.annotation包而不是javax.transaction。Spring提供了一个EnableTransactionManagement注解配置在配置类上来开启声明式事务的支持,使用了该注解后Spring会自动扫描@Transactional追。

    注解事务行为

    事务的传播行为

    • REQUIRED:表示业务方法需要在一个事务中处理,如果业务方法执行时已经在一个事务中,则加入该事务,否则重新开启一个事务。这也是默认的事务传播行为;

    • NOT_SUPPORTED:声明业务方法不需要事务,如果业务方法执行时已经在一个事务中,则事务被挂起,等方法执行完毕后,事务恢复进行;

    • REQUIRES_NEW:表明业务方法需要在一个单独的事务中进行,如果业务方法进行时已经在一个事务中,则这个事务被挂起,并重新开启一个事务来执行这个业务方法,业务方法执行完毕后,原来的事务恢复进行;

    • MANDATORY:该属性指定业务方法只能在一个已经存在的事务中进行,业务方法不能发起自己的事务;如果业务方法没有在一个既有的事务中进行,容器将抛出异常;

    • SUPPORTS:该属性指定,如果业务方法在一个既有的事务中进行,则加入该事务;否则,业务方法将在一个没有事务的环境下进行;

    • NEVER:指定业务方法不可以在事务中进行,如果业务方法执行时已经在一个事务中,容器将抛出异常;

    • NESTED:该属性指定,如果业务方法在一个既有的事务中执行,则该业务方法将在一个嵌套的事务中进行;否则,按照REQUEIRED来对待。它使用一个单独的事务,这个事务可以有多个rollback点,内部事务的rollback对外部事务没有影响,但外部事务的rollback会导致内部事务的rollback。这个行为只对DataSourceTransactionManager有效。

    事务的隔离级别

    使用@Transactional的Isolation属性可以指定事务的隔离级别。但事务的隔离级别是由底层的数据库实现的,并不是由Spring来实现。

    • READ_UNCOMMITTED:会出现脏读、不可重复读和幻读问题;

    • READ_COMMITTED:会出现不可重复读和幻读问题;

    • REPEATABLE_READ:会出现幻读问题;

    • SERIALIZABLE:串行化,不会出现上面的问题。

      一般的数据库默认提供的是READ_COMMITTED隔离级别,如sqlserver2000;Mysql默认提供的是REPEATABLE_READ。


      这里写图片描述

    默认遇到运行期例外(throw new RuntimeException("注释");)会回滚,即遇到不受检查(unchecked)的例外时回滚;
    而遇到需要捕获的例外(throw new Exception("注释");)不会回滚,即遇到受检查的例外(就是非运行时抛出的异常,编译器会检查到的异常叫受检查例外或说受检查异常)时,需我们指定方式来让事务回滚 ,如下:

    @Transactional(rollbackFor=Exception.class) //指定回滚,遇到异常Exception时回滚
        public void methodName() {
           throw new Exception("注释");
           
        }
    @Transactional(noRollbackFor=Exception.class)//指定不回滚,遇到运行期例外(throw new RuntimeException("注释");)会回滚
        public ItimDaoImpl getItemDaoImpl() {
            throw new RuntimeException("注释");
        } 
    

    类级别使用@Transactional

    @Transactional不仅可以注解在方法上,也可以注解在类上,当注解在类上的时候,表明此类的所有public方法都是开启事务的,如果类级别和方法级别同时使用了@Transactional注解,则使用在类级别的注解会重载方法级别的注解。在使用类级别注解的时候,推荐将类中的select查询方法同时加上@Transactional(readOnly=true)属性。

    Spring Data JPA的事务支持

    Spring Data JPA对所有默认的方法都开启了事务支持,且对所有的查询类事务默认启用readOnly=true属性。这一点可以去看SimpleJpaRepository的源码。的确如此。

    Spring Boot的事务支持

    自动配置的事务管理器

    在使用JDBC作为数据访问技术的时候,SpringBOOT为我们定义PlatformTransactionManager的实现DataSourceTransactionManager的Bean,配置见org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration.class类中的定义.
      在使用JPA作为数据访问的技术的时候,SpringBoot为我们定义了一个PlatformTransactionManager的实现JpaTransactionManager的Bean,配置见org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.class类中的定义

    自动开启注解事务的支持

    Spring Boot专门用于配置事务的类为org.springframework.boot.autoconfigure.jdbc.transaction.TransactionAutoConfiguration,此配置类依赖于JpaBaseConfiguration和DataSourceTransactionManagerAutoConfiguration。而在DataSourceTransactionManagerAutoConfiguration配置里还开启了对声明式事务的支持。所以在Spring Boot中无需显示启用@EnableTransactionManagement注解。

    参考书籍 JavaEE开发的颠覆者-SpringBoot实战

    相关文章

      网友评论

          本文标题:Spring的声明式事务

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