Spring 事务管理简介

Spring 框架中事务管理有两种方式:一种是传统的编程式事务管理,即通过编写代码实现的事务管理;另一种是基于 AOP 技术实现的声明式事务管理。由于在 Spring 框架中,编程式事务管理很少使用,所以我们只对Spring 的声明式事务管理进行详细讲解。

Spring 的声明式事务管理在底层采用了 AOP 技术,其最大的优点在于无须通过编程的方式管理事务,只需要在配置文件中进行相关的规则声明,就可以将事务规则应用到业务逻辑中。

Spring 实现声明式事务管理主要有两种方式

基于 XML 文件方式的声明式事务管理。

通过 Annotation 注解方式的事务管理。

1、Spring 声明式事务管理原理

Spring 事务管理简介_第1张图片

 

2、数据库事务的特性

2.1 什么是事务

事务是作为一个逻辑单元执行的一系列操作。一个事务工作单元必须有四个特性原子性、一致性、隔离性、持久性。只有这样才能成为一个事务。

2.2 事务的作用

事物对于数据库的作用是对数据的一系列操作,要么全部成功,要么全部失败,防止中间状态的出现,以确保数据库中的数据始终处于正确的状态。

2.3 事务的 ACID 特性

数据库的事务的 ACID 特性由数据库的事务管理系统来保证的。

原子性(Atomicity):事务中的所有操作作为一个整体像原子一样不可分割,要么全部成功,要么全部失败。

一致性(Consistency):事务的执行不能破坏数据库数据的完整性和一致性,一个事务在执行之前和执行之后,数据库都必须处于一致性状态。如果数据库系统在运行过程中发生故障,有些事务尚未完成就被迫中断,这些未完成的事务对数据库所作的修改有一部分已写入物理数据库,这时数据库就处于一种不正确的状态,也就是不一致的状态。

隔离性(Isolation):并发执行的事务不会相互影响 ,其对数据库的影响和它们串行执行时一样。比如多个用户同时往一个账户转账,最后账户的结果应该和他们按先后次序转账的结果一样。

持久性(Durability):事务一旦提交,其对数据库的更新就是持久的。任何事务或系统故障都不会导致数据丢失。

一致性是事务的最终目的,原子性、隔离性、持久性都是为了实现一致性。

3、事务的隔离性

3.1 不考虑隔离性会导致的三个问题

3.1.1 脏读

脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。读未提交

Spring 事务管理简介_第2张图片

3.1.2 不可重复读

是指 A 事务读取到了 B 事务已经提交的更改数据,在同个时间段内,两次查询的结果不一致。

 Spring 事务管理简介_第3张图片

 

3.1.3 幻读(虚读)

A 事务读取到 B 事务提交的新增数据,幻读一般发生在数据统计事务中。

Spring 事务管理简介_第4张图片

 

3.2 解决办法(四种隔离级别)

3.2.1 Read Uncommited(读取未提交内容)

读未提交,顾名思义,就是一个事务可以读取另一个未提交事务的数据。但是,读未提交产生了脏读,采用 Read Commited 可以解决脏读问题

3.2.2 Read Commited(读取提交内容)

读提交,顾名思义,就是一个事务要等另一个事务提交后才能读取数据。读提交,若有事务对数据进行更新(UPDATE)操作时,读操作事务要等待这个更新操作事务提交后才能读取数据,可以解决脏读问题。但是,读提交两次查询会产生不同的查询结果,就会造成不可重复读问题,采用 Repeatable Read 可以解决此问题。

3.2.3 Repeatable Read(重复读)

重复读,就是在开始读取数据(事务开启)时,不再允许修改操作。重复读可以解决不可重复读问题。应该明白的一点就是,不可重复读对应的是修改,即 UPDATE 操作。但是可能还会有幻读问题。因为幻读问题对应的是插入INSERT 操作,而不是 UPDATE 操作。采用Serializable 可以解决幻读问题。

3.2.4 Serializable(可串行化)

Serializable 是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。

Yes:可能出现。No:不会出现。

Spring 事务管理简介_第5张图片

 

注意:

  • 大多数数据库默认的事务隔离级别是 Read committed,比如 Sql Server , Oracle。

  • Mysql 的默认隔离级别是 Repeatable read。

  • 隔离级别的设置只对当前链接有效。对于使用 MySQL 命令窗口而言,一个窗口就相当于一个链接,当前窗口设置的隔离级别只对当前窗口中的事务有效;对于 JDBC操作数据库来说,一个 Connection 对象相当于一个链接,而对于 Connection 对象设置的隔离级别只对该 Connection 对象有效,与其他链接 Connection 对象无关。

你可能感兴趣的:(spring,java,后端)