Springboot AOP事务处理说明

1. Spring 中事务简介

1.1 事务定义

事务(Transaction)是一个业务,是一个不可分割的逻辑工作单元,基于事务可以更好的保证业务的正确性。

1.2 事务特性

事务具备ACID特性,分别是:

  • 原子性(Atomicity):一个事务中的多个操作要么都成功要么都失败。
  • 一致性(Consistency):例如存钱操作,存之前和存之后的总钱数应该是一致的。
  • 隔离性(Isolation):事务与事务应该是相互隔离的。
  • 持久性(Durability):事务一旦提交,数据要持久保存。
    说明:目前市场上在事务一致性方面,通常会做一定的优化,比方说只要最终一致就可以了,这样的事务我们通常会称之为柔性事务(只要最终一致就可以了).

2. Spring 中事务管理

2.1 Spring 中事务方式概述

Spring框架中提供了一种声明式事务的处理方式,此方式 基于AOP代理,可以将具体业务逻辑与事务处理进行解耦。也就是让我们的业务代码逻辑不受污染或少量污染,就可以实现事务控制。
在SpringBoot项目中,其内部提供了事务的自动配置,当我们在项目中添加了指定依赖 spring-boot-starter-jdbc 时,框架会自动为我们的项目注入事务管理器对象,最常用的为DataSourceTransactionManager 对象。

2.2 Spring 中事务管理实现

本小节重点讲解实际项目中最常用的注解方式的事务管理,以注解@Transactional配置方式为例,进行实践分析。
基于@Transactional 注解进行声明式事务管理的实现步骤分为两步:

  • 启用声明式事务管理,在项目启动类上添加@EnableTransactionManagement,新版本中也可不添加(例如新版Spring Boot项目)。
  • @Transactional注解添加到合适的业务类或方法上,并设置合适的属性信息。
    其代码示例如下:
@Transactional(timeout = 30,
				readOnly = false ,
				isolation = Isolation. READ_COMMITTED ,
				rollbackFor = Throwable. class ,
				propagation = Propagation. REQUIRED )
@Service
public class implements SysUserService {
	@Transactional(readOnly = true )
	@Override
	public PageObject<SysUserDeptVo> findPageObjects( String username , Integer  pageCurrent ) {}
}

其中,代码中的@Transactional注解用于描述类或方法,告诉spring框架我们要在此类的方法执行时进行事务控制,其具体说明如下:。

  • @Transactional注解应用在类上时表示类中所有方法启动事务管理,并且一般用于事务共性的定义。
  • @Transactional描述方法时表示此方法要进行事务管理,假如类和方法上都有@Transactional注解,则方法上的事务特性优先级比较高。

2.3 @Transactional 常用属性应用说明

  • timeout:事务的超时时间,默认值为-1,表示没有超时显示。如果配置了具体时间,则超过该时间限制但事务还没有完成,则自动回滚事务。这个时间的记录方式是在事务开启以后到sql语句执行之前。
  • read-only:指定事务是否为只读事务,默认值为 false;为了忽略那些不需要事务的方法,比如读取数据,可以设置read-only为true。对添加,修改,删除业务read-only的值应该为false。
  • rollback-for:用于指定能够触发事务回滚的异常类型,如果有多个异常类型需要指定,各类型之间可以通过逗号分隔。
  • no-rollback- for:抛出no-rollback-for 指定的异常类型,不回滚事务。
  • isolation:事务的隔离级别,默认值采用 DEFAULT。当多个事务并发执行时,可能会出现脏读,不可重复读,幻读等现象时,但假如不希望出现这些现象可考虑修改事务的隔离级别(但隔离级别越高并发就会越小,性能就会越差) DEFAULT, READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE;
    Springboot AOP事务处理说明_第1张图片

Spring事务管理是基于接口代理(JDK)或动态字节码(CGLIB)技术,然后通过AOP实施事务增强的。当我们执行添加了事务特性的目标方式时,系统会通过目标对象的代理对象调用DataSourceTransactionManager对象,在事务开始的时,执行doBegin方法,事务结束时执行doCommitdoRollback方法。

2.4 Spring中事务隔离级别

  1. DEFAULT:这是默认值,表示使用底层数据库的默认隔离级别。对大部分数据库而言,通常这值就是:READ_COMMITTED。
  • READ_UNCOMMITTED:该隔离级别表示一个事务可以读取另一个事务修改但还没有提交的数据。该级别不能防止脏读和不可重复读,因此很少使用该隔离级别。
  1. READ_COMMITTED:该隔离级别表示一个事务只能读取另一个事务已经提交的数据。该级别可以防止脏读,这也是大多数情况下的推荐值。
  2. REPEATABLE_READ:该隔离级别表示一个事务在整个过程中可以多次重复执行某个查询,并且每次返回的记录都相同。即使在多次查询之间有新增的数据满足该查询,这些新增的记录也会被忽略。该级别可以防止脏读和不可重复读
  3. SERIALIZABLE:所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。

2.5 Spring 中事务传播特性

事务传播(Propagation)特性指"不同业务(service)对象"中的事务方法之间相互调用时,事务的传播方式,
Springboot AOP事务处理说明_第2张图片
其中,常用事务传播方式如下:

  1. @Transactional(propagation=Propagation.REQUIRED)
    如果没有事务创建新事务, 如果当前有事务参与当前事务, Spring 默认的事务传播
    行为是PROPAGATION_REQUIRED,它适合于绝大多数的情况。假设 ServiveX#methodX()都工作在事务环境下(即都被 Spring 事务增强了),假设程序中存在如下的调用链:Service1#method1()->Service2#method2()->Service3#method3(),那么这 3 个服务类的 3 个方法通过 Spring 的事务传播机制都工作在同一个事务中。
    Springboot AOP事务处理说明_第3张图片
@Transactional(propagation = Propagation.REQUIRED)
@Override
public List<Node> findZtreeMenuNodes() {
	return sysMenuDao .findZtreeMenuNodes();
}

当有一个业务对象调用如上方法时,此方法始终工作在一个已经存在的事务方法,或者是由调用者创建的一个事务方法中。

  1. @Transactional(propagation=Propagation.REQUIRES_NEW)。必须是新事务, 如果有当前事务, 挂起当前事务并且开启新事务Springboot AOP事务处理说明_第4张图片
@Transactional (propagation = Propagation. REQUIRES_NEW )
@Override
public void saveObject(SysLog entity ) {
	sysLogDao .insertObject( entity );
}

当有一个业务对象调用如上业务方法时,此方法会始终运行在一个新的事务中。

  1. @Transactional(propagation=Propagation.PROPAGATION_SUPPORT)
    如果外层有事务,则加入外层事务,如果外层没有事务,则直接使用非事务方式执行。完全依赖外层的事务
  2. @Transactional(propagation=Propagation.PROPAGATION_NOT_SUPPORT)
    该传播机制不支持事务,如果外层存在事务则挂起,执行完当前代码,则恢复外层事务,无论是否异常都不会回滚当前的代码
  3. @Transactional(propagation=Propagation.PROPAGATION_NEVER)
    该传播机制不支持外层事务,即如果外层有事务就抛出异常
  4. @Transactional(propagation=Propagation.PROPAGATION_MANDATORY)
    与NEVER相反,如果外层没有事务,则抛出异常
  5. @Transactional(propagation=Propagation.PROPAGATION_NESTED)
    该传播机制的特点是可以保存状态保存点,当前事务回滚到某一个点,从而避免所有的嵌套事务都回滚,即各自回滚各自的,如果子事务没有把异常吃掉,基本还是会引起全部回滚的。 传播规则回答了这样一个问题:一个新的事务应该被启动还是被挂起,或者是一个方法是否应该在事务性上下文中运行。

3. Spring 中事务管理小结

Spring 声明式事务是 Spring 最核心,最常用的功能。由于 Spring 通过 IOC 和AOP的功能非常透明地实现了声明式事务的功能,对于一般的开发者基本上无须了解Spring声明式事务的内部细节,仅需要懂得如何配置就可以了。但对于中高端开发者还需要了解其内部机制。

你可能感兴趣的:(springboot,spring,boot)