MySQL 事务 ACID 四大特性 + 四大隔离级别(面试高频考点)

一.啥么是事务?

事务把一组SQL语句打包成为一个整体,在这组SQL的执行过程中,要么全部成功,要么全部失败。

二.事务的ACID特性

事务的AICD特性值得是Atomicity(原子性),Consistency(一致性),Isolation(隔离性)和Durability(持久性)。

  • Atomicity(原子性):一个事务的所有操作,要么全部成功,要么全部失败,不会出现只执行了一半的情况,如果事务在执行的过程中发生错误,会回滚到初始状态,就像这个事务没有执行过一样。
  • Consistency(一致性):在事务开始之前和事务结束之后,数据库的完整性不会被破环。
  • Ioslation(隔离性):数据库允许许多个并发事务同时对数据进行读写和修改,隔离性可以防止多个事务并发执行时由于交叉执行而导致的数据不一致。
  • Durability(持久性):事务处理结束后,对数据的修改将永久的写入存储介质,即使系统发生故障也不会丢失。

三.为啥么要使用事务?

事务具备的ACID特性,是我们使用事务的原因,在我们日常的业务场景中有大量的场景要使用事务来保证。支持事务的数据库能够接话我们的编程模型,不需要我们去考虑各种各样的潜在错误和并发问题,在使用事务过程中,要么提交,要么回滚,不用去考虑网络异常,服务器宕机等其他因素,因此我们为您经常借出的事务本质上是数据库对ACID模型的一个实现,是为应用层服务的。

四.如何使用事务

4.1查看支持事务的存储引擎

要使用事务那么数据库就要支持事务,在MySQL中支持事务的引擎是InnoDB,可以通过show engines;语句查看:

4.2语法

#开始一个新的事务

start transaction;

#或

begin;//建议使用,因为简单好记

#提交当前事务,并对更改持久保存

commit;

#回滚当前事务,取消更改

rollback;

• START TRANSACTION 或 BEGIN 开始⼀个新的事务;

• COMMIT 提交当前事务,并对更改持久化保存;

• ROLLBACK 回滚当前事务,取消其更改;

• ⽆论提交还是回滚,事务都会关闭

4.3自动/手动提交事务

默认情况下,MySQL是自动提交事务的,也就是说我们执行的每个修改操作,比如插入删除和更新,都会自动开启一个事务并在语句执行完之后自动提交,发生异常时自动回滚。

查看当前事务是否自动提交可以使用以下语句:

可以通过以下语句设置事务为自动或手动提交

设置事务⾃动提交

mysql> SET AUTOCOMMIT=1; # ⽅式⼀

mysql> SET AUTOCOMMIT=ON; # ⽅式⼆

设置事务⼿动提交

mysql> SET AUTOCOMMIT=0; # ⽅式⼀

mysql> SET AUTOCOMMIT=OFF; # ⽅式⼆

注意:

  • 只要使用start transaction或begin开启事务,必须要通过commit提交才能持久化,与是否设置set autocommit无关
  • 手动提交模式下,不用显示开启事务,执行修改操作后,提交或回滚时直接使用commit或rollback
  • 已提交的事务不能回滚
  1. 事务的隔离性和隔离级别

6.1 什么是隔离性

MySQL服务可以同时被多个客⼾端访问,每个客⼾端执⾏的DML语句以事务为基本单位,那么不 同的客⼾端在对同⼀张表中的同⼀条数据进⾏修改的时候就可能出现相互影响的情况,为了保证不同 的事务之间在执⾏的过程中不受影响,那么事务之间就需要要相互隔离,这种特性就是隔离性。

6.2 隔离级别

• READ UNCOMMITTED ,读未提交

• READ COMMITTED ,读已提交

• REPEATABLE READ ,可重复读(默认)

• SERIALIZABLE ,串⾏化

6.3 不同隔离级别存在的问题

READ UNCOMMITTED-读未提交与脏读

事务A中执⾏了⼀条 INSERT 语句,在没有执⾏ COMMIT 的情况下,会在事务B中被读取到,此时如果事务A执⾏回滚操作,那么事务B中读取到事务 A写⼊的数据将没有意义,我们把这个理象叫做 "脏读"

READ COMMITTED-读已提交与不可重复读

事务A先对某条数据进⾏了查询,之后事务 B对这条数据进⾏了修改,并且提交( COMMIT )事务,事务A再对这条数据进⾏查询时,得到了事务B 修改之后的结果,这导致了事务A在同⼀个事务中以相同的条件查询得到了不同的值,这个现象要"不 可重复读"。

REPEATABLE READ-可重复读与幻读

事务A查询了⼀个区间的记录得到 结果集A,事务B向这个区间的间隙中写⼊了⼀条记录并提交,事务A再查询这个区间的结果集时会查 到事务B新写⼊的记录得到结果集B,两次查询的结果集不⼀致,这个现象就是"幻读"。

SERIALIZABLE-串⾏化

可以解决所有并发中的安 全问题