【MySQL】MySQL事务
目录
1. 事务的引入
2. 事务的概念
3. 回滚
4. 事务的使用
5. 事务的特性
6. 数据库的并发执行
7. 并发执行常出现的问题
8. MySQL隔离级别
1. 事务的引入
在日常的开发场景中,经常会涉及到“一气呵成”的操作,比如在向别人转账的时候,转账进行了一半,程序突然崩溃/数据库崩溃/机器没电等,一系列突发情况,这时候可以转账成功,也可能自己这边显示扣款了,但是对方没有收到,造成一定的纠纷,引入事务就可以解决上述的这种情况
2. 事务的概念
事务可以理解为将多个sql语句打包成为一个整体,要么这些sql语句全部被执行,要么一个都不执行,这里还涉及一个重要的操作—回滚(可以理解为撤回操作),当这个整体中的sql语句执行了一半,没有执行完,但是系统崩溃了,则会进行回滚(让数据库恢复到事务开始前的状态)
3. 回滚
回滚(Rollback)是指将未完成事务中的所有已执行操作撤销的过程,使数据库恢复到事务开始前的状态。
回滚的实现只要依靠日志,在数据被修改之前,会先记录回滚的日志,确保日志被持久化写入硬盘后,才会真正的执行
4. 事务的使用
(1)开启事务—START TRANSACTION
(2)事务的实行—执行多个SQL语句
(3)回滚—ROLLBACK
(4)提交—COMMIT
当所有的sql语句执行完后,最后执行commit操作,表示将所有的操作保存在数据库中,如果执行rollback操作,表示撤销事务中的所有操作
5. 事务的特性
(1)原子性
通过借助回滚操作,保证一系列操作,要么全部被执行,要么都不执行
(2)一致性
事务执行前后,各个主键之间的约束不能发现改变(参照实体完整性和参照完整性)
(3)隔离性
数据库在并发处理多个事务的时候,彼此之间是相互独立的,互不干扰
(4)持久性
事务做出的修改,在硬盘上需要持久化保存,重启服务器,数据依然存在且有效
6. 数据库的并发执行
首先要清楚,数据库的并发处理是非常常见的
- MySQL是客户端服务器结构
- 一个服务器可以给多个客户端提供服务
- 多个客户端可能在同一时刻执行不同的事务
- 数据库服务器就需要在同一个时刻并发处理多个事务
并发处理带来的好处就是,效率的大大提升,但是效率的提升往往会出现一些其他的问题(数据异常),我们需要控制好隔离级别,才能解决好数据异常的问题
7. 并发执行常出现的问题
(1)脏读
场景分析:
- 事务A在写数据的过程中,事务B在读数据(前提同一份数据)
- 事务A突然修改了之前的数据,导致B读到的之前的数据,是一个无效数据(脏数据)
解决:
- 规定数据A在写数据的时候,不能进行读数据,给写操作加锁
(2)不可重复读
前置条件:数据A在写数据的时候,不能进行读数据,
场景分析:
- 在数据A写完之后,事务B进行了多次读操作,在事务B读取过程中,事务A又进行了写入,导致读取的数据出现差异(不可重复读)
解决:
- 在数据B读操作的时候,不能进行写操作,加入读锁
(3)幻读
前置条件:加入了读写锁,也就是解决了脏读和不可重复读问题
场景分析:
- 事务A连续读取文件A的时候,事务B没有写文件A,但是写入了文件B,事务A两次读取虽然数据内容没有改变,但是结构集变了(幻读)
解决:
- 串行化的方式,此时完全没有了并发,虽然效率最低,但是数据是最准确的
在实际的开发中,我们需要根据具体需求,设计不同的隔离级别,有的场景追求正确性,有的场景追求效率
8. MySQL隔离级别
1. READ UNCOMMITTED (读未提交)
- 解决:无
- 问题:可能出现脏读、不可重复读和幻读
2. READ COMMITTED (读已提交)
- 解决:脏读
- 问题:可能出现不可重复读和幻读
3. REPEATABLE READ (可重复读)
- 解决:脏读和不可重复读
- 问题:可能出现幻读
4. SERIALIZABLE (可串行化)
- 解决:脏读,幻读,不可重复读
- 问题:无
- 缺点:并发性能最低
MySQL中提供了“隔离级别”,我们可以根据具体的需求,修改配置文件,设置不同的隔离级别