1. 事务
1.1. 需求
数据操作在顺序执行的过程中,任何一步操作都有可能发生异常,异常会导致后续操作无法完成,此时由于业务逻辑并未正确的完成,之前成功操作数据的并不可靠,需要在这种情况下进行回退,此时事务管理就显得尤为重要。
1.2. 定义
事务(Transaction),一般是指要做的或所做的事情。事务管理是针对一系列数据库操作进行管理,一个事务包含一个或多个SQL语句,是逻辑管理的工作单元(原子单元)。
1.3. 特性
事务应该具有4个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性。
- 原子性(atomicity):一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。
- 一致性(consistency):事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
- 隔离性(isolation):一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
- 持久性(durability):持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
1.4. 作用
事务的作用就是为了保证用户的每一个操作都是可靠的,事务中的每一步操作都必须成功执行,只要有发生异常就回退到事务开始未进行操作的状态。
1.5. Spring
- 事务管理是Spring框架中最为常用的功能之一,有两种实现方式,分别是编程式事务管理和声明式事务管理两种方式。
编程式事务管理: 编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate。
声明式事务管理: 建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。
声明式事务有两种方式:
一种是在配置文件(xml)中做相关的事务规则声明:
另一种是基于@Transactional 注解的方式:
- Springboot默认对jpa、jdbc、mybatis开启了事务,当引入spring-boot-starter-jdbc或spring-boot-starter-data-jpa依赖的时候,默认分别注入DataSourceTransactionManager或JpaTransactionManager,事物就默认开启了。当然,你可以按照需要自己配置相关的事物管理器。
- Springboot首先使用注解@EnableTransactionManagement开启事务支持(Springboot自动完成,不需要人为干涉),
org.springframework.boot.autoconfigure.transaction.TransactionalAutoConfiguration开启了对声明 式事务的支持,这个完全归功于强大的Springboot-AutoConfiguration:
然后在访问数据库的Service方法上添加注解 @Transactional或者在控制器Controller的方法直接添 加@Transactional注解开启事务。
- @Transactional可以作用于接口、接口方法、类以及类方法上。被 @Transactional 注解的方法,则该方法将支持事务属性。如果@Transactional注解在类上,则整个类的所有public方法都默认支持事务。
- Spring团队的建议是你在具体的类(或类的方法)上使用 @Transactional 注解,而不要使用在类所要实现的任何接口上。你当然可以在接口上使用 @Transactional 注解,但是这将只能当你设置了基于接口的代理时它才生效。因为注解是 不能继承 的,这就意味着如果你正在使用基于类的代理时,那么事务的设置将不能被基于类的代理所识别,而且对象也将不会被事务代理所包装(将被确认为严重的)。
- @Transactional 注解只被应用到public 可见度的方法上。 如果你在 protected、private 或者 package-visible 的方法上使用 @Transactional 注解,它也不会报错, 但是这个被注解的方法将不会生效事务设置。
- 在声明事务时,可以通过value属性指定配置的事务管理器名,例如:@Transactional(value="transactionManagerPrimary") ,还可以对事务进行隔离级别和传播行为的控制。
- Spring的AOP即声明式事务管理默认是针对unchecked exception回滚。也就是默认对RuntimeException()异常或是其子类进行事务回滚;checked异常,即Exception可try{}捕获的不会回滚,因此对于我们自定义异常,通过rollbackFor进行设定。
