MySQL 事务

事务是一组 DML(insert、delete、update)语句的集合,一个事务中的语句要么全部执行要么全部不执行。

SQL 语句分为四类:数据查询语言 DQL(select),数据操纵语言 DML(insert、delete、update),数据定义语言DDL(create)和数据控制语言 DCL(grant、rollback、commit)。

MySQL 中 InnoDB 支持事务而 MyISAM 不支持,事务默认自动提交,即除非显式地开始一个事务,否则每个 DML 语句都被当做一个单独的事务自动执行。

显示开启事务以 begin 命令开始,以 commit 或 rollback 命令结束。

事务特性 ACID

  • 原子性(Atomicity)

原则性指事务中包含的所有操作,要么都做,要不都不做,不会出现一部分生效而另一部分未生效的情况。

  • 一致性(Consistency)

一致性指数据在事务处理前后都满足业务规则的约束,数据状态均合法,不会违背任何的数据完整性。

ACID 中的一致性和分布式系统 CAP(一致性、可用性和分区容忍性) 中的一致性意义不同,CAP 中的一致性指同一数据在每一个节点上有相同的拷贝。

  • 隔离性(Isolation)

隔离性指允许多个并发事务同时对数据进行修改,保证并行事务处理能够互不干扰。

  • 持久性(Durability)

持久性指事务处理结束后对数据的修改是永久的,即使系统故障也不会丢失。

事务执行过程

自动提交开启,即 autocommit = ON 时,如果通过 begin 或 start transaction 命令显式开启事务,结束时需要通过 commit 提交事务,或通过 rollback 回滚事务。如果不显式地开启事务,则每个 DML 语句都被当做一个单独的事务自动执行。

自动提交关闭,即 autocommit = OFF 时,事务在对数据进行操作时自动开启,结束事务同样需执行 commit 提交或执行 rollback 回滚。

『自动提交开启且显式开启事务』,或『自动提交关闭』,如果没有显式地结束事务,则事务会在提交 DDL 语句或再次输入 begin(start transaction)时隐式提交(session 级别),在退出会话、连接超时或关机等情况隐式回滚。

truncate 和 delete

truncate 和 delete 语句都可以清空表内数据,区别是 truncate 是 DDL 语句、在事务中不能回滚且会重置当前自增值,而 delete 是 DML 语句、可以回滚。

不再需要表时用 drop,仍要保留表但删除所有记录时用 truncate,要删除部分记录时用 delete。

事务隔离级别

MySQL InnoDB 存储引擎实现了 SQL 标准的 4 中隔离级别,用于限定事务内外数据改变时的可见性。低隔离级别支持更高的并发,系统开销低,但可能出现脏读、幻读等现象。

  • 读未提交 (RU,read uncommitted),指在一个事务中可以读取到其他事务未提交的数据变化,容易出现脏读,不建议在生产环境中使用。
  • 读已提交(RC,read committed),指在一个事务中可以读到其他事务已经提交的数据变化,也叫作不可重复读,允许幻读发生,是 Oracle 数据库的默认事务隔离级别。
  • 可重复读(RR,repetable read),指事务从开始到结束的过程中允许反复读取数据,且读到的数据均为事务刚开始时看到的数据,避免了脏读、不可重复读和幻读,是 MySQL 默认的事务隔离级别。
  • 串行(serializable),每次读操作都要加表级共享锁,每次写操作都要加表级排他锁。串行会降低 InnoDB 的并发能力,不建议在生产环境中使用。

脏读:事务 A 中读取到事务 B 中未提交修改的数据,事务 B 回滚,A 读到的就是脏数据。

不可重复读:事务 A 多次读取同一数据,事务 B 在事务 A 多次读取的过程中修改或删除数据并提交,导致事务 A 多次读取同一数据结果不一致。

幻读:在一个事务中读取到了其他事务新增的数据。

不可重复读针对 update 和 delete,幻读针对 insert。

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • © 2016-2020 姜越

谢谢老板

支付宝
微信