概念
事务定义
事务,就是一组操作数据库的动作集合。事务是现代数据库理论中的核心概念之一。如果一组处理步骤或者全部发生或者一步也不执行,我们称该组处理步骤为一个事务。当所有的步骤像一个操作一样被完整地执行,我们称该事务被提交。由于其中的一部分或多步执行失败,导致没有步骤被提交,则事务必须回滚到最初的系统状态。
事务特点
- 原子性:一个事务中所有对数据库的操作是一个不可分割的操作序列,要么全做要么全不做
- 一致性:数据不会因为事务的执行而遭到破坏
- 隔离性:一个事务的执行,不受其他事务的干扰,即并发执行的事务之间互不干扰
- 持久性:一个事务一旦提交,它对数据库的改变就是永久的。
事务实现机制
Spring为事务管理提供了丰富的功能支持。Spring 事务管理分为编程式和声明式的两种方式。
- 编程式事务管理: 编程式事务管理使用TransactionTemplate或者直接使用底层的 PlatformTransactionManager。对于编程式事务管理,spring 推荐使用 TransactionTemplate。
- 声明式事务管理: 建立在 AOP 之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。
- 声明式事务管理不需要入侵代码,更快捷而且简单,推荐使用。
声明式事务有两种方式:
- 一种是在配置文件(xml)中做相关的事务规则声明(因为很少用本文不讲解)
- 另一种是基于**@Transactional**注解的方式。注释配置是目前流行的使用方式,推荐使用。
在应用系统调用声明了 @Transactional 的目标方法时,Spring Framework 默认使用 AOP 代理,在代码运行时生成一个代理对象,根据 @Transactional 的属性配置信息,这个代理对象决定该声明 @Transactional 的目标方法是否由拦截器 TransactionInterceptor 来使用拦截,在 TransactionInterceptor 拦截时,会在目标方法开始执行之前创建并加入事务,并执行目标方法的逻辑,最后根据执行情况是否出现异常,利用抽象事务管理器 AbstractPlatformTransactionManager 操作数据源 DataSource 提交或回滚事务。
Spring AOP 代理有 CglibAopProxy 和 JdkDynamicAopProxy 两种,以 CglibAopProxy 为例,对于 CglibAopProxy,需要调用其内部类的 DynamicAdvisedInterceptor 的 intercept 方法。对于 JdkDynamicAopProxy,需要调用其 invoke 方法。
开启事务
注解 @Transactional 的使用
注解 @Transactional 常用配置
参 数 名 称
功 能 描 述
readOnly
用于设置当前事务是否为只读事务,设置为 true 表示只读,false 则表示可读写,默认值为 false。例如:@Transactional(readOnly=true)
rollbackFor
用于设置需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,则进行事务回滚。例如:指定单一异常类:@Transactional(rollbackFor=RuntimeException.class);指定多个异常类:@Transactional(rollbackFor={RuntimeException.class, Exception.class})
transactionManager / value
多个事务管理器托管在 Spring 容器中时,指定事务管理器的 bean 名称
rollbackForClassName
用于设置需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,则进行事务回滚。例如:指定单一异常类名称 @Transactional(rollbackForClassName=”RuntimeException”) 指定多个异常类名称:@Transactional(rollbackForClassName={“RuntimeException”,”Exception”})
noRollbackFor
用于设置不需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,不进行事务回滚。例如:指定单一异常类:@Transactional(noRollbackFor=RuntimeException.class) 指定多个异常类:@Transactional(noRollbackFor={RuntimeException.class, Exception.class})
noRollbackForClassName
用于设置不需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,不进行事务回滚。例如:指定单一异常类名称:@Transactional(noRollbackForClassName=”RuntimeException”) 指定多个异常类名称:@Transactional(noRollbackForClassName={“RuntimeException”, ”Exception”})
propagation
用于设置事务的传播行为。例如:@Transactional(propagation=Propagation.NOT_SUPPORTED, readOnly=true)
isolation
用于设置底层数据库的事务隔离级别,事务隔离级别用于处理多事务并发的情况,通常使用数据库的默认隔离级别即可,基本不需要进行设置
timeout
该属性用于设置事务的超时秒数,默认值为 - 1 表示永不超时
事物超时设置:@Transactional(timeout=30) ,设置为 30 秒
Propagation 的属性(事务的传播行为)
例如:@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)
Propagation 属性
含义
REQUIRED
默认值 在有 transaction 状态下执行;如当前没有 transaction,则创建新的 transaction;
SUPPORTS
如当前有 transaction,则在 transaction 状态下执行;如果当前没有 transaction,在无 transaction 状态下执行;
MANDATORY
必须在有 transaction 状态下执行,如果当前没有 transaction,则抛出异常 IllegalTransactionStateException;
REQUIRES_NEW
创建新的 transaction 并执行;如果当前已