暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL事务

福尔摩俞 2024-07-16
91

事务 Transaction

事务的定义:

  • 事务是一条或多条DML语句组成,事务用来维护数据的完整性,保证这一组SQL语句要么全部执行成功,要么全部执行失败;
  • 在MySQL中只有Innodb引擎才支持事务;
  • 通常一个事务对应一个完整业务。

事务的ACID特性

  • 原子性: Atomic 一个事务是一个不可分割的工作单位,其中的操作要么都做,要么都不做;如果事务中一个sql语句执行失败,则已执行的语句也必须回滚,数据库退回到事务前的状态。
  • 一致性:Consistent 事务执行结束后,数据库的完整性约束没有被破坏,事务执行的前后都是合法的数据状态。
  • 隔离性:Isolated 事务内部的操作与其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
  • 持久性: Durable 事务一旦提交,其所作做的修改会永久保存到数据库中

事务的周期

事务开始:
  • begin或“transaction” 都是显示开启一个事务, MySQL5.5之后不需要手动加begin,只要是是执行DML语句,会自动在SQL语句前添加begin.
事务提交:
  • commit: 提交事务,事务提交成功就具备ACID特性了。
事务回滚:
  • rollback: 回滚事务, 将已执行的操作回滚回去。
自动提交:
  • 在MySQL中默认开始了自动提交(autocommit),在自动提交模式下,如果没有“start transaction”或begin显示地开始一个事务,那么每条SQL语句都会被当成一个事务执行提交操作。
  • 查询自动提交模式
mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
1 row in set (0.01 sec)

  • 关闭自动提交

关闭自动提交后,所有的SQL语句都在一个事务中直到执行commit或rollback ,该事务结束。

mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)

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


MySQL事务特征ACID的实现原理

1. 原子性

原子性指的是事务是一个不可分割的单元,其中的操作要么都成功,要么都失败;如果事务中有任何SQL语句执行失败,则已经执行的语句必须回滚,数据库退回到事务开始前的状态。

原子性的实现原理
  • Innodb 引擎提供了两种事务日志,redo log(重做日志)和undo log(回滚日志),其中redo log用于保证事务的持久性,undo log用于实现事务的原子性和隔离性。
  • undo log : 当事务对数据库进行修改时,Innodb 会生成对应的undo log ,如果有事务失败或调用了rollback,就可以利用undo log中的信息将数据回滚到修改前的状态。
  • undo log记录了SQL执行的相关信息,当发生回滚时,Innodb会根据undo log 做与之相反的操作:例如对于insert,回滚时执行delete;对于delete,回滚时
    执行insert;对于update,回滚时执行相反的update.
  • 每条数据变更都会产生一条undo log

2. 一致性

一致性是指事务结束后,数据库的完整性约束没有被破坏,事务执行前后都是合法的数据状态.

  • 一致性是事务的最终追求目标,原子性、持久性、隔离性都是为了保障数据的一致性;
  • 数据库自身也为一致性提供保障,例如不能违反字段的约束;

3. 隔离性

隔离性是指并发事务之间相互不影响.

隔离性的实现原理:
  • 一个事务的写操作对另一个事务的写操作影响: 锁机制保证隔离性
  • 一个事务的写操作对另一个事务的读操作影响: MVCC保证隔离性
在并发事务下,读操作存在的问题:
  1. 脏读(Dirty Read): 事务A可以读到事务B未提交的数据(脏数据);
  2. 不可重复读(Non-Repeatable Read): 在事务A中先后读取同一个数据,两次读到的结果不一致;
  3. 幻读(Phantom):在事务A中按照某个条件先后两次查询数据,两次查询结果条数不一样;不可重复读和幻读的区别是,前者是数据变了,后者是数据的行变了.
事务的隔离级别:

隔离级别的作用就是让事务之间互相隔离,互不影响,保证事务的一致性,解决并发事务下脏读、不可重读读、幻读等问题。

隔离级别 可解决的问题
读未提交RU(Read Uncommitted)
读已提交RC(Read Committed) 脏读
可重读读RR(Repeatable Read) 脏读、不可重复读
可串行化SR(Serializable) 脏读、不可重复读、幻读
  • 隔离级别比较
  1. 可串行化>可重复读>读已提交>读未提交
  • 对性能影响比较
  1. 可串行化>可重复读>读已提交>读未提交

隔离级别越高,所消耗的MySQL性能就越大,为了平衡隔离级别和性能,一般建议将隔离级别设置未可重复读,MySQL的默认隔离级别就是可重复读。

  • 查看隔离级别
mysql> show variables like 'transaction_isolation';
+-----------------------+-----------------+
| Variable_name         | Value           |
+-----------------------+-----------------+
| transaction_isolation | REPEATABLE-READ |
+-----------------------+-----------------+
1 row in set (0.00 sec)

  • 修改隔离级别
  1. 全局修改, 对当前会话无效,对之后的会话起作用
mysql> set global transaction isolation level SERIALIZABLE;
Query OK
  1. 当前会话修改,对当前会话的后续事务有效,不影响当前正在执行的事务
mysql> set session transaction isolation level SERIALIZABLE;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like 'transaction_isolation';
+-----------------------+--------------+
| Variable_name         | Value        |
+-----------------------+--------------+
| transaction_isolation | SERIALIZABLE |
+-----------------------+--------------+
1 row in set (0.00 sec)

隔离级别的实现原理:

隔离级别通过MVCC技术来实现

  • MVCC: Multi-Version Concurrency Control 多版本并发控制: 在同一时刻,不同事务读取到的数据存在多个版本,即多个版本的数据可以共存。

4. 持久性

持久性是指,当事务一旦提交,事务所做的修改就会永久保存到数据库。

持久性的实现原理:
  • 持久性是通过redo log来实现的
redo log:
  • redo log 称为重做日志,是物理日志,记录的是数据页的物理修改,当系统意外宕机时,在重启MySQL后,可以将未持久保存的数据写入到磁盘。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论