声明式事务
Spring Boot 中的事务是基于 AOP,可以支持声明式事务,使用注解选择将要使用事务的方法。在企业里,业务处理中使用事务的地方还是比较多。只要对将要使用事务的地方添加注解,就可以轻松解决事务处理的问题,因此,声明式事务是本章的重点。
@Transaction注解
在7.1.2中隔离级别的使用方式一,里面有一个注解 @Transaction,下面就介绍一下这个注解。
Spring 在配置类上使用 @EnableTransactionManagement,将会自动扫描被标注 @Transaction 的类或者方法,启动声明式事务。
对于 @Transaction 的使用,可以放在方法上,也可以放在类上。如果放在类上,说明类中的所有 public 方法都会开发事务;如果方法与类上都有 @Transaction,则方法上的注解重载类的注解。
需要注意的是,这个注解同样可以被放在接口上。如果放在接口上,使用接口上的事务,其实是有限制的,就是在 AOP 代理时,只能使用 JDK 进行代理,如果想使用 cglib 动态代理就不允许。所以在实际使用中,也需考虑这点。
在 @Transaction 注解上,可以根据需要进行配置,表7.4是它常用的参数与说明。

有些属性需要举例,才能更好地理解,例子如下。
-
@Transaction(rollbackFor={"Exception.class","RunTimeException.class"})。
-
@Transaction(rollbackForClassName={"Exception","RunTimeException"})。
-
@Transaction(norollbackFor={"Exception.class","RunTimeException.class"})。
-
@Transaction(norollbackForClassName={"Exception","RunTimeException"})。
事务超时的属性 timeout,其实是事务允许执行的最长时间,使用 int 描述时间,单位为秒。默认设置的时间是事务系统的超时值,如果没有设置,则表示 none,也就是永不超时的意思;如果设置了,且超过了设置的时间,事务将会自动进行回滚。
事务管理器
数据访问层都用自己的事务管理框架,而 Spring Boot 的事务管理机制则通过统一的机制来处理不同的框架。Spring 中有一个 PlatformTransactionManager 接口,负责事务的管理。先来看源码,代码如下所示。
package org.springframework.transaction;
import org.springframework.lang.Nullable;
public interface PlatformTransactionManager {
//获取事务
TransactionStatus getTransaction(@Nullable TransactionDefinition var1) throws TransactionException;
//提交
void commit(TransactionStatus var1) throws TransactionException;
//回滚
void rollback(TransactionStatus var1) throws TransactionException;
}
在上文的源码中,可以看到接口中有三个方法,分别是获取事务、提交和回滚。其中,有几个参数需要说明。TransactionDefinition 类是一个带有事务属性的接口,在接口中有隔离级别、超时时间、传播行为、是否只读等属性。DefaultTransactionDefinition 是此接口的默认实现方式。TransactionStatus 是接口的状态,有四种状态,是否是新创建的、是否已经完成、是否只回滚、是否有回滚点。
在 Spring 中,不同的访问层框架都可以实现这个接口,比较常见的有下面的几个。
当使用 JPA 时,在 pom 文件中将会引入 spring-boot-starter-jpa,并在 Spring Boot 的 JpaBaseConfiguration 类中构建出 JpaTransactionManager。下面是定义的源码。
package org.springframework.boot.autoconfigure.orm.jpa;
@Bean
@ConditionalOnMissingBean
public PlatformTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
if (this.transactionManagerCustomizers != null) {
this.transactionManagerCustomizers.customize(transactionManager);
}
return transactionManager;
}
当使用 JDBC 时,我们会引入依赖 spring-boot-starter-jdbc,并在 Spring Boot 的 DataSourceTransactionManagerAutoConfiguration 类中构建出 DataSourceTransactionManager。下面是定义的源码。
package org.springframework.boot.autoconfigure.jdbc;
@Bean
@ConditionalOnMissingBean(PlatformTransactionManager.class)
public DataSourceTransactionManager transactionManager(
DataSourceProperties properties) {
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(
this.dataSource);
if (this.transactionManagerCustomizers != null) {
this.transactionManagerCustomizers.customize(transactionManager);
}
return transactionManager;
}
除此之外还有几个常见的实现策略,如表7.5所示。
