2021-02-27 数据库事务及隔离级别

一、事务的四大特性(简称ACID)

事务的使用是数据库管理系统区别文件系统的重要特征之一。
事务拥有四个重要的特性:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)

1、原子性(Atomicity)

事务是数据库的逻辑工作单位,事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。例如,如果一个事务需要新增 100 条记录,但是在新增了 10 条记录之后就失败了,那么数据库将回滚对这 10 条新增的记录。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位。


image.png

2、一致性(Consistency)

指事务将数据库从一种状态转变为另一种一致的的状态。事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。事务开始前和结束后,数据库的完整性约束没有被破坏。例如工号带有唯一属性,如果经过一个修改工号的事务后,工号变的非唯一了,则表明一致性遭到了破坏。


image.png

3、隔离性(Isolation)

一个事务的执行不能被其他事务干扰。要求每个读写事务的对象对其他事务的操作对象能互相分离,即该事务提交前对其他事务不可见。 也可以理解为多个事务并发访问时,事务之间是隔离的,一个事务不应该影响其它事务运行效果。这指的是在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。例如一个用户在更新自己的个人信息的同时,是不能看到系统管理员也在更新该用户的个人信息(此时更新事务还未提交)。
注:MySQL 通过锁机制来保证事务的隔离性。
这个会在后续讲解数据库隔离级别

4、持续性/永久性(Durability)

一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。即使发生宕机的故障,数据库也能将数据恢复,也就是说事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。这只是从事务本身的角度来保证,排除 RDBMS(关系型数据库管理系统,例如 Oracle、MySQL 等)本身发生的故障。
注:MySQL 使用 redo log 来保证事务的持久性。

二、事务的隔离级别

多个事务并发访问时,事务之间是隔离的,一个事务不应该影响其它事务运行效果。
这指的是在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。事务查看数据更新时,数据所处的状态要么是另一事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看到中间状态的数据。

   在Windows中,如果多个进程对同一个文件进行修改是不允许的,Windows通过这种方式来保证不同进程的隔离性:

企业开发中,事务最复杂问题都是由事务隔离性引起的。当多个事务并发时,SQL Server利用加锁和阻塞来保证事务之间不同等级的隔离性。一般情况下,完全的隔离性是不现实的,完全的隔离性要求数据库同一时间只执行一条事务,这样会严重影响性能。想要理解SQL Server中对于隔离性的保障,首先要了解并发事务之间是如何干扰的。

1、事务之间的相互影响

事务之间的相互影响分为几种,分别为:脏读,不可重复读,幻读,丢失更新

a)、脏读(Dirty Read)

一个事务读到了另一个未提交事务修改过的数据

image.png

image.png

b)、不可重复读(Non-Repeatable Read)

一个事务只能读到另一个已经提交的事务修改过的数据,并且其他事务每对该数据进行一次修改并提交后,该事务都能查询得到最新值。(不可重复读在读未提交和读已提交隔离级别都可能会出现)

image.png

image.png

c)、幻读(Phantom)

一个事务先根据某些条件查询出一些记录,之后另一个事务又向表中插入了符合这些条件的记录,原先的事务再次按照该条件查询时,能把另一个事务插入的记录也读出来。(幻读在读未提交、读已提交、可重复读隔离级别都可能会出现)

image.png

例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样.
image.png

2、事务的隔离级别

MySQL的事务隔离级别一共有四个,分别是读未提交、读已提交、可重复读以及可串行化。 MySQL的隔离级别的作用就是让事务之间互相隔离,互不影响,这样可以保证事务的一致性。 隔离级别比较:可串行化>可重复读>读已提交>读未提交 隔离级别对性能的影响比较:可串行化>可重复读>读已提交>读未提交 由此看出,隔离级别越高,所需要消耗的MySQL性能越大(如事务并发严重性),为了平衡二者,一般建议设置的隔离级别为可重复读,MySQL默认的隔离级别也是可重复读。

image.png

a)、读未提交(READ UNCOMMITTED)

image.png

b)、读已提交(READ COMMITTED)

image.png

c)、可重复读(REPEATABLE READ)

image.png

d)、可串行化(SERIALIZABLE)

image.png

image.png

image.png

image.png

image.png

三、spring 事务传播机制

参考文章:
spring 事务的传播机制看这篇就够了
Spring 事务传播机制
带你读懂Spring 事务——事务的传播机制

image.png

四、参考文档

彻底搞懂 MySQL 事务的隔离级别
Innodb中的事务隔离级别和锁的关系
MySQL 事务隔离级别和锁

你可能感兴趣的:(2021-02-27 数据库事务及隔离级别)