Home » Code » Mysql » Mysql 事务相关

Mysql 事务相关

本文使用的 MySQL 版本为 5.7.19。

数据库一般包括以下四种语言,分别是DDL(Data Definition Language,数据定义语言),DML(Data Manipulation Language,数据操纵语言),DCL(Data Control Language,数据控制语言),TCL(Transaction Control Language,事务控制语言)。事务,是针对DML 语句而言的。

事务,就是为了保证多个应用程序在并发访问数据库时,可以在这些应用程序之间提供一个隔离方法,以防止彼此的操作互相干扰。因此,事务具有以下四个特性:

  • 原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。
  • 一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义是数据库中的数据应满足完整性约束。
  • 隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行。
  • 持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中。

其中的隔离性,有几种隔离级别,不同的隔离级别,会导致其一致性有所差异,汇总如下:

 

下面具体演示下不同隔离级别下的一致性表现。

默认情况下,MySQL 的事务是隐式开启并自动提交的,每执行一条 DML 语句,就开启了事务并且进行了提交。

mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
1 row in set (0.01 sec)

为演示在不同隔离级别下导致的一致性问题,需要将自动提交设置为 OFF。执行:set autocommit = 0。在一个会话中执行,只针对当前会话有效。我们打开两个会话 session A 和 session B,分别执行此语句。

读未提交——READ UNCOMMITTED

在上面的操作中,session A 读到了 session B 中未提交的数据(name =  ‘李四’),这主是脏读——Dirty Read。如果 session B 最终进行了回滚,那得到的数据就完全是不存在的!相当的离谱,因此,没有数据库的默认隔离级别会是READ UNCOMMITTED。

读已提交——READ COMMITTED

如图,读已提交级别虽然已经避免了脏读(序号6的操作),但当事务提交后,还是影响了另一个事务的结果(序号8),这就是不可重复读。Oracle 数据库默认是这个级别。

可重复读——REPEATABLE READ

在这个隔离级别,不可重复读已经不存在(序号7、8),单纯的 select 语句也无法找到新插入的数据,但是当我们尝试对新插入的数据进行修改时,却又返回成功,仿佛我们可以修改一些“不存在”的数据,这就是幻读!MySQL 数据库默认是这个级别。

串行化——SERIALIZABLE

这是最严格的隔离级别,上边提到的三种问题都不会发生,一致性高度保证!

ddd

Leave a Reply

Your email address will not be published. Required fields are marked *

*

Time limit is exhausted. Please reload CAPTCHA.