事务 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保证隔离性
在并发事务下,读操作存在的问题:
- 脏读(Dirty Read): 事务A可以读到事务B未提交的数据(脏数据);
- 不可重复读(Non-Repeatable Read): 在事务A中先后读取同一个数据,两次读到的结果不一致;
- 幻读(Phantom):在事务A中按照某个条件先后两次查询数据,两次查询结果条数不一样;不可重复读和幻读的区别是,前者是数据变了,后者是数据的行变了.
事务的隔离级别:
隔离级别的作用就是让事务之间互相隔离,互不影响,保证事务的一致性,解决并发事务下脏读、不可重读读、幻读等问题。
| 隔离级别 | 可解决的问题 |
|---|---|
| 读未提交RU(Read Uncommitted) | 无 |
| 读已提交RC(Read Committed) | 脏读 |
| 可重读读RR(Repeatable Read) | 脏读、不可重复读 |
| 可串行化SR(Serializable) | 脏读、不可重复读、幻读 |
- 隔离级别比较
- 可串行化>可重复读>读已提交>读未提交
- 对性能影响比较
- 可串行化>可重复读>读已提交>读未提交
隔离级别越高,所消耗的MySQL性能就越大,为了平衡隔离级别和性能,一般建议将隔离级别设置未可重复读,MySQL的默认隔离级别就是可重复读。
- 查看隔离级别
mysql> show variables like 'transaction_isolation';
+-----------------------+-----------------+
| Variable_name | Value |
+-----------------------+-----------------+
| transaction_isolation | REPEATABLE-READ |
+-----------------------+-----------------+
1 row in set (0.00 sec)
- 修改隔离级别
- 全局修改, 对当前会话无效,对之后的会话起作用
mysql> set global transaction isolation level SERIALIZABLE;
Query OK
- 当前会话修改,对当前会话的后续事务有效,不影响当前正在执行的事务
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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




