详细解析MySQL事务

本篇文章给大家带来了关于mysql的相关知识,其中主要介绍了MySQL的事务ACID特性和MySQL事务控制流程的语法,并介绍事务并发处理中可能出现的异常情况,比如脏读、幻读、不可重复读等

    本篇文章给大家带来了关于mysql的相关知识,其中主要介绍了MySQL的事务ACID特性和MySQL事务控制流程的语法,并介绍事务并发处理中可能出现的异常情况,比如脏读、幻读、不可重复读等等,最后介绍事务隔离级别,希望对大家有帮助。

推荐学习:mysql学习教程

在实际业务场景中,如何保证操作的完整性是一个重要的议题,依次执行一系列逻辑强关联的操作,如果在中途发生了错误,就很有可能导致数据的错乱。

设想一下在 ATM 取钱的场景,当我们取出一千元的时候,ATM 会在清点完成后一次性吐出一千元,而不是分十次每次吐出一百元,这就是为了保证操作的完整性,要么完整的取走一千元,扣除余额,要么一分钱都没有取走,余额不变,而不会出现中途机器故障导致数据不一致的情况。这样的一次完整操作叫做事务 transaction,一个事务中的所有操作要么全部成功执行,要么完全不执行。

本文将会介绍 MySQL 的事务 ACID 特性和 MySQL 事务控制流程的语法,并介绍事务并发处理中可能出现的异常情况,比如脏读、幻读、不可重复读等等,最后介绍事务隔离级别。

关于实现事务隔离性的锁和 MVCC,将会在之后的文章进行介绍。

ACID 特性

事务处理是一种对必须整批执行的 MySQL 操作的管理机制,在事务过程中,除非整批操作全部正确执行,否则中间的任何一个操作出错,都会回滚 (Rollback) 到最初的安全状态以确保不会对系统数据造成错误的改动。

之前的文章中我们提到过,MySQL 5.5 之后,默认的存储引擎从 MyISAM 替换成了 InnoDB,这其中的一个重要原因就是因为 InnoDB 支持事务,我们用 SHOW ENGINES 来看一下 MySQL 中对各种存储引擎的描述。在这里插入图片描述 事务最重要的四个特性通常被称为 ACID 特性A - Atomicity 原子性: 一个事务是一个不可分割的最小单位,事务中的所有操作要么全部成功,要么全部失败,没有中间状态。原子性主要是通过事务日志中的回滚日志(undo log)来实现的,当事务对数据库进行修改时,InnoDB 会根据操作生成相反操作的 undo log,比如说对 insert 操作,会生成 delete 记录,如果事务执行失败或者调用了 rollback,就会根据 undo log 的内容恢复到执行之前的状态。

C - Consistency 一致性: 事务执行之前和执行之后数据都是合法的一致性状态,即使发生了异常,也不会因为异常引而破坏数据库的完整性约束,比如唯一性约束等。

I - Isolation 隔离性: 每个事务是彼此独立的,不会受到其他事务的执行影响,事务在提交之前对其他事务不可见。隔离性通过事务的隔离级别来定义,并用锁机制来保证写操作的隔离性,用 MVCC 来保证读操作的隔离性,将在下文详细介绍。

D - Durability 持久性: 事务提交之后对数据的修改是持久性的,即使数据库宕机也不会丢失,通过事务日志中的重做日志(redo log)来保证。事务修改之前,会先把变更信息预写到 redo log 中,如果数据库宕机,恢复后会读取 redo log 中的记录来恢复数据。

事务控制语法

MySQL 事务控制有几个重要节点,分别是事务的开启,提交,回滚和保存点。

开启事务代表事务开始执行,语句为 START TRANSACTION 或者 BEGIN,提交事务代表将事务中的所有更新都写到磁盘的物理数据库,事务正常执行结束,语句为 COMMIT,如果发生异常需要回滚,语句为 ROLLBACK。要注意的是,一旦事务已经提交,就不能回滚了,因此,在代码执行过程中捕获到异常的时候需要直接执行 rollback 而不是 commit。

比如 A 向 B 转账 100 元的事务: