事务管理,在日常的CRUD开发过程中是必不可少的,Spring为事务管理提供了丰富的功能支持,一般分为:编程式式事务声明式事务两种形式。声明式事务将具体的事务处理和业务逻辑分开,解耦合,在实际中比较常用,以下介绍声明式事务的使用及其原理。

声明式事务的基本使用

使用@Transactional注解来实现声明式事务管理,其原理是使用AOP。
第一步,创建事务配置信息,可以使用xml配置,也可以使用@EnableTransactionManagement注解启用事务管理功能。

1
2
3
4
5
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>

第二步,将@Transactional注解添加在合适的方法上,来将整个方法变成一个事务。

事务的属性

事务属性包含五个方面:隔离级别传播行为回滚机制事务超时只读

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public @interface Transactional {
@AliasFor("transactionManager")
String value() default "";
// 事务管理器
@AliasFor("value")
String transactionManager() default "";
// 事务传播行为
Propagation propagation() default Propagation.REQUIRED;
// 事务隔离级别
Isolation isolation() default Isolation.DEFAULT;
// 事务超时事件,-1标识永久,超时期一过就回滚
int timeout() default -1;
// 只读事务,会优化锁
boolean readOnly() default false;
// 触发事务回滚的异常类型,多个用逗号分隔
Class<? extends Throwable>[] rollbackFor() default {};

String[] rollbackForClassName() default {};
// 某些异常类型不执行事务回滚
Class<? extends Throwable>[] noRollbackFor() default {};

String[] noRollbackForClassName() default {};
}

隔离级别

隔离级别 含义
ISOLATION_DEFAULT 使用数据库的默认隔离级别
ISOLATION_READ_UNCOMMITTED 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读
ISOLATION_READ_COMMITTED 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
ISOLATION_REPEATABLE_READ 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生
ISOLATION_SERIALIZABLE 最高的隔离级别,完全服从ACID的隔离级别,确保阻止脏读、不可重复读以及幻读

传播行为

传播行为 含义
PROPAGATION_REQUIRED 当前方法必须运行在事务中。如果当前存在事务,加入已存在的事务中,否则启动一个新事务。
PROPAGATION_SUPPORTS 当前方法支持运行在事务中。如果当前存在事务,加入已存在的事务中,否则非事务运行。
PROPAGATION_MANDATORY 当前方法必须运行在事务中。如果当前存在事务,加入已存在的事务中,否则抛出异常。
PROPAGATION_REQUIRED_NEW 当前方法必须运行在自己的事务中。如果当前存在事务,挂起已存在的事务中,启动一个新事务执行。
PROPAGATION_NOT_SUPPORTED 当前方法不支持运行在事务中。如果当前存在事务,挂起已存在的事务中,非事务运行。
PROPAGATION_NEVER 当前方法不能运行在事务中。如果当前存在事务,抛出异常。
PROPAGATION_NESTED 类似于 PROPAGATION_REQUIRED_NEW,但前者是两个独立的事务,而它是嵌套事务。

实现机制

注意事项