漫谈MySQL八-什么是事务

目录

1.事务的基础概念

1.1.什么是事务?

1.1.1.原子性(atomicity)

1.1.2.一致性(consistency)

1.1.3.持久性(durability)

1.1.4.隔离性(isolation)

1.2.事务并发引发的问题

1.2.1.脏读

1.2.2.不可重复读

1.2.3.幻读


大家好,我是王老狮,事务是我们学习SQL必须要了解的知识了,因为事务的存在我们才能保证程序能够按照我们想要的状态去执行,并且也是面试中经常遇到的一些问题,今天我们就来回顾下什么是事务。

1.事务的基础概念

1.1.什么是事务?

事务是数据库管理系统(DBMS)执行过程中的一个逻辑单位(不可再进行分割),由一个有限的数据库操作序列构成(多个 DML 语句,select 语句不包含事务),要不全部成功,要不全部不成功。

例如:A 给 B 要划钱,A 的账户-1000 元, B 的账户就要+1000 元,这两个 update 语句必须作为一个整体来执行,不然 A 扣钱了,B 没有加钱这种情况就是错误的。那么事务就可以保证 A 、B 账户的变动要么全部一起发生,要么全部一起不发生。

事务特性

事务应该具有 4 个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为 ACID 特性。

  • 原子性(atomicity)
  • 一致性(consistency)
  •  隔离性(isolation)
  • 持久性(durability)

1.1.1.原子性(atomicity)

一个事务必须被视为一个不可分割的最小单元,整个事务中的所有操作要么全部提交成功,要么全部失败,对于一个事务来说,不能只执行其中的一部分操作。

比如:

  1. 王老狮借给小明200块钱,将钱通过银行卡转给小明
  2. 首先王老狮银行卡里要减少200块钱
  3. 小明同学的银行卡里要增加200块钱

整个事务的操作要么全部成功,要么全部失败,不能出现王老狮卡里的钱减少,但是小明同学的卡里钱没有增加。如果原子性不能保证,就会很自然的出现一致性问题,不满足能量守恒定律了嘛。

1.1.2.一致性consistency

一致性是指事务将数据库从一种一致性转换到另外一种一致性状态,在事务开始之前和事务结束之后数据库中数据的完整性没有被破坏。

王老狮借给小明钱:

王老狮银行卡扣除 500 元

小明银行卡卡增加 500

扣除的钱(-500) 与增加的钱(500) 相加应该为 0,或者说 王老狮和小明的账户的钱加起来,前后应该不变。

1.1.3.持久性durability

一旦事务提交,则其所做的修改就会永久保存到数据库中。此时即使系统崩溃,已经提交的修改数据也不会丢失。

1.1.4.隔离性isolation)

一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。如果隔离性不能保证,会导致什么问题?

王老狮借给小明生活费,借了两次,每次都是 500,王老狮的卡里开始有 1200,小明的卡里开始有 300,从理论上,借完后,王老狮的的卡里有 200,小明的卡里应该有 1300。

我们将 王老狮向小明同时进行的两次转账操作分别称为 T1 和 T2,在现实世界中 T1 和 T2 是应该没有关系的,可以先执行完 T1,再执行 T2,或者先执行完 T2,再执行 T1,结果都是一样的。但是很不幸,真实的数据库中 T1 和T2 的操作可能交替执行的,执行顺序就有可能是:

如果按照上图中的执行顺序来进行两次转账的话,最终我们看到,王老狮的账户里还剩 700 元钱,相当于只扣了 500 元钱,但是小明的账户里却成了1300 元钱,多出现了 500 元,这银行岂不是要亏死了?

所以对于现实世界中状态转换对应的某些数据库操作来说,不仅要保证这些操作以原子性的方式执行完成,而且要保证其它的状态转换不会影响到本次状态转换,这个规则被称之为隔离性。

1.2.事务并发引发的问题

我们知道 MySQL 是一个客户端/服务器架构的软件,对于同一个服务器来说,可以有若干个客户端与之连接,每个客户端与服务器连接上之后,就可以称之为一个会话(Session)。每个客户端都可以在自己的会话中向服务器发出请求语句,一个请求语句可能是某个事务的一部分,也就是对于服务器来说可能同时处理多个事务。

在上面我们说过事务有一个称之为隔离性的特性,理论上在某个事务对某个数据进行访问时,其他事务应该进行排队,当该事务提交之后,其他事务才可以继续访问这个数据,这样的话并发事务的执行就变成了串行化执行。但是对串行化执行性能影响太大,我们既想保持事务的一定的隔离性,又想让服务器在处理访问同一数据的多个事务时性能尽量高些,当我们舍弃隔离性的时候,可能会带来什么样的数据问题呢?

1.2.1.脏读

当一个事务读取到了另外一个事务修改但未提交的数据,被称为脏读。

事务 2 修改了一行记录,但是没有提交。然后事务 1 读取到了未提交的数据,如果事务 2 回滚其更改的数据或者再次更新,那么在事务 1 中看到的记录可能就是错误的。事务 1 读取到了 King 老师余额为 1500 的记录,但是事务 2 执行了回滚操作,这时并不存在 King 老师余额为 1500 记录。

1.2.2.不可重复读

当事务内相同的记录被检索两次,且两次得到的结果不同时,此现象称为不可重复读。

事务 2 对记录做了修改并提交成功,这意味着修改的记录对其他事务是可见的, 因此事务 1 两次读取的 money 值不同。

​​​​​​​1.2.3.幻读

在事务执行过程中,另一个事务将新记录添加到正在读取的事务中时,会发生幻读。当事务 1 重复执行 SELECT… WHERE 语句时,在这期间事务 2 执行 INSERT语句插入了满足where 条件的新记录。于是事务 1 执行两次一模一样的SELECT… WHERE,返回却是两组不同的记录。

 有的同学会有疑问,那如果事务 2 中是删除了符合的记录而不是插入新记录,那事务 1 中之后再根据条件读取的记录变少了,这种现象算不算幻读呢?明确说一下,在 MySQL 中这种现象不属于幻读,幻读强调的是一个事务按照某个相同条件多次读取记录时,后读取时读到了之前没有读到的记录。

那对于先前已经读到的记录,之后又读取不到这种情况,算啥呢?其实这相当于对每一条记录都发生了不可重复读的现象。幻读只是重点强调了读取到了之前读取没有获取到的记录。

  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王老狮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值