Spring的声明式事务
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注解。
推荐阅读
-
基于MQ的2PC分布式事务
-
深入探究js中的隐式变量声明
-
基于spring+quartz的分布式定时任务框架实现
-
完美解决Spring声明式事务不回滚的问题
-
详解基于Spring Boot/Spring Session/Redis的分布式Session共享解决方案
-
如何使用Spring+redis实现对session的分布式管理
-
Springboot-dubbo-fescar 阿里分布式事务的实现方法
-
Spring Boot Security 结合 JWT 实现无状态的分布式API接口
-
Spring整合Quartz定时任务并在集群、分布式系统中的应用
-
Spring中事务管理的四种方法(银行转账为例)