SpringBoot-事务控制

概念回顾

事务

数据库事务( transaction)是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的全部数据库操作组成。

SpringBoot-事务控制_第1张图片

事务的特性:(ACID)

1) 原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。

2) 一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义是数据库中的数据应满足完整性约束。

3) 隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行。

4) 持久性(Durability):一个事务一旦提交,他对数据库的修改应该永久保存在数据库中。

为什么要使用事务

1) 为数据库操作序列提供了一个从失败中恢复到正常状态的方法,同时提供了数据库即使在异常状态下仍能保持一致性的方法。

2) 当多个应用程序在并发访问数据库时,可以在这些应用程序之间提供一个隔离方法,以防止彼此的操作互相干扰。

3) 当事务被提交给了 DBMS,则 DBMS 需要确保该事务中的所有操作都成功完成且其结果被永久保存在数据库中,如果事务中有的操作没有成功完成,则事务中的所有操作都需要被回滚,回到事务执行前的状态;同时,该事务对数据库或者其他事务的执行无影响,所有的事务都好像在独立的运行。

4) 但在现实情况下,失败的风险很高。在一个数据库事务的执行过程中,有可能会遇上事务操作失败、数据库系统/操作系统失败,甚至是存储介质失败等情况。这便需要 DBMS 对一个执行失败的事务执行恢复操作,将其数据库状态恢复到一致状态(数据的一致性得到保证的状态)。为了实现将数据库状态恢复到一致状态的功能,DBMS 通常需要维护事务日志以追踪事务中所有影响数据库数据的操作。

回顾 Spring 中的事务

1、所有的数据访问技术都有事务处理机制,这些技术提供了 API 用于开启事务,提交事务来完成数据操作或者在发生时回滚数据。

2、Spring 的事务机制,是采用统一的机制处理来自不同数据访问技术的事务处理,提供了一个接口PlatformTransactionManager,已经为不同数据访问技术可以进行不同的实现,如下表。

SpringBoot-事务控制_第2张图片

SpringBoot-事务控制_第3张图片

3、Spring 并不直接管理事务,而是提供了多种事务管理器 ,他们将事务管理的职责委托给 Hibernate 或者 JTA 等持久化机制所提供的相关平台框架的事务来实现。Spring 事务管理器的接口是:PlatformTransactionManager ,通过这个接口,Spring 为各个平台如 JDBC、Hibernate 等都提供了对应的事务管理器,但是具体的实现就是各个平台自己的事情了。

4、Spring 事务管理可以分为两种:编程式和声明式。

5、Spring 编程式事务管理:编程式事务管理是侵入性事务管理,就是通过硬编码代码的方式进行事务的控制。对于编程式事务管理,Spring 推荐使用 TransactionTemplate。

6、Spring 声明式事务:声明式事务管理建立在 AOP 之上,其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,执行完目标方法之后根据执行的情况提交或者回滚。

回顾 Spring 声明式事务

在 Java 工程中一般有两种方式:使用 xml 配置文件和@Transactional 注解

xml 配置文件



    



    
        
        
        
        
        
    



    
    

2、使用@Transactional 注解

1) 第一步,在 xml 配置文件中添加如清单 1 的事务配置信息。



    

2) 第二步,将@Transactional 注解添加到合适的类或方法上,并设置合适的属性信息。

属性

类型

说明

propagation

枚举型:Propagation

可选的传播性设置。使用举例:@Transactional(propagation=Propagation.REQUIRES_NEW)

isolation

枚举型:Isolation

可选的隔离性级别。使用举例:@Transactional(isolation=Isolation.READ_COMMITTED)

timeout

int型(以秒为单位)

事务超时。使用举例:@Transactional(timeout=10)

readOnly

布尔型

是否为只读型事务。使用举例:@Transactional(readOnly=true)

rollbackFor

一组Class类的实例,必须是Throwable的子类

一组异常类,遇到时必须进行回滚。使用举例:@Transactional(rollbackFor={SQLException.class} ),多个异常可用英文逗号隔开

rollbackForClassName

一组Class类的实例,必须是Throwable的子类

一组异常类名,遇到时必须进行回滚。使用举例:@Transactional(rollbackForClassName={"SQLException"} ),多个异常可用英文逗号隔开

noRollbackFor

一组Class类的实例,必须是Throwable的子类

一组异常类,遇到时必须不回滚

noRollbackForClassName

一组Class类的实例,必须是Throwable的子类

一组异常类名,遇到时必须不回滚

3) propagation:事务传播机制

required

REQUIRED(默认值)表示如果存在一个事务,则支持当前事务;如果当前没有事务,则开启一个事务

supports

SUPPORTS:表示如果当前存在一个活动的事务,则支持当前事务;如果当前没有事务,则按非事务方式执行。

mandatory

MANDATORY:表示如果存在一个事务,则支持当前事务;如果当前没有一个活动的事务,则抛出异常。

requires_news

REQUIRES_NEWS:表示总是开启一个新的事务。如果一个事务已经存在,则先将这个存在的事务挂起,然后开启新事务执行该方法。

not_supported

NOT_SUPPORTED:表示总是以非事务方式执行。如果一个事务已经存在,则先将这个存在的事务挂起,然后执行该方法。

never

NEVER:表示总是以非事务方式执行。如果当前存在一个活动的事务,则抛出异常。其中REQUIRED能满足大多数都事务需求。

nested

NESTED:表示如果当前存在一个活动的事务,则创建一个事务作为当前事务的嵌套事务运行;如果没有当前事务,该取值与REQUIRED相同。

4) isolation:事务隔离级别

DEFAULT

(默认值)表示使用数据库默认的事务隔离级别,默认值就是READ_COMMITTED

READ_UNCOMMITTED

表示一个事务可以读取另一个事务修改但还没有提交的数据。不能防止脏读和不可重复读,因此很少使用该隔离级别

READ_COMMITTED

表示一个事务只能读取另外一个事务已经提交的数据,可以防止脏读,这也是大多数情况下的推荐值

REPEATABLE_READ

表示一个事务在整个过程中可以多次重复执行某个查询,并且每次返回的记录都相同。即使在多次查询之间有新增的数据满足该查询,这些新增的记录也会被忽略。可以防止脏读和不可重复读

SERIALIZABLE

所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。

5) @Transactional 的 rollbackFor 属性

a) 默认情况下,如果在事务中抛出了 RuntimeException 或者 Error,则Spring 将回滚事务;除此之外,Spring 不会回滚事务。

b) 如果在事务中抛出其他类型的异常,并期望 Spring 能够回滚事务,可以 指 定 rollbackFor 。 例 : @Transactional(propagation= Propagation.REQUIRED,rollbackFor= Exception.class)

Spring Boot 中的事务控制:实际上就是 Spring 的事务控制

第一步:要在 Spring Boot 中支持事务,首先要导入 Spring boot 提供的 JDBC 或 JPA 依赖。如果加载了 mybatis-spring-boot-starter 依赖,这个中间件已经 依赖了 spring-boot-starter-jdbc(不需要引入)SpringBoot-事务控制_第4张图片

在 Spring Boot 中,当我们使用了 spring-boot-starter-jdbc 或 spring-boot-starter-data-jpa 依赖的时候,框架会自动默认分别注入

DataSourceTransactionManager 或 JpaTransactionManager。所以我们不 需要任何额外配置就可以用@Transactional 注解进行事务的使用。

第二步:启动类上添加@EnableTransactionManagement 注解开启事务支持

第三步:将@Transactional 注解添加到合适的类或方法上,并设置合适属性信息。

你可能感兴趣的:(#,Spring,Boot,spring,boot,数据库,后端,java,事务,开发语言)