MYSQL学习
1、事务的四大特性(ACID)(面试)
目标
了解事务的四大特性
讲解
数据库的事务必须具备ACID特性,ACID是指 Atomicity(原子性)、Consistensy(一致性)、Isolation(隔离性)和Durability(持久性)的英文缩写。
1、隔离性(Isolation)
多个用户并发的访问数据库时,一个用户的事务不能被其他用户的事务干扰,多个并发的事务之间要相互隔离。
一个事务的成功或者失败对于其他的事务是没有影响。2个事务应该相互独立。
举例:
a 给b转账 –>叫做事务A
c 给d 转账 –>叫做事务B
事务A和事务B之间不会相互影响。
2、持久性(Durability)
指一个事务一旦被提交,它对数据库的改变将是永久性的,哪怕数据库发生异常,重启之后数据亦然存在。
举例:
a=1000、b=1000转账
开启事务
a-100
b+100
提交
结果: a 900 b 1100
即使事务提交以后再发生异常,a和b的数据依然不会变。a就是900 b就是1100。
3、原子性(Atomicity)
原子性是指事务包装的一组sql(一组业务逻辑)是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
4、一致性(Consistency)
一个事务在执行之前和执行之后 数据库都必须处于一致性状态。
如果事务成功的完成,那么数据库的所有变化将生效。
如果事务执行出现错误,那么数据库的所有变化将会被回滚(撤销),返回到原始状态。
事务的成功与失败,最终数据库的数据都是符合实际生活的业务逻辑。一致性绝大多数依赖业务逻辑和原子性。
举例1: a=1000、b=1000 转账 100
a - 100
b + 100
结果: a + b = 2000
如果a转账失败了,那么b也得失败。不能因为a失败了,a依然是1000.但是b却成功了,b却变成了1100.那么结果是2100了,这样是不符合事务的一致性的。
小结
事务四个特性?
原子性
一致性
隔离性
持久性
事务特性 | 含义 |
---|---|
一致性(Consistency) | 事务前后数据的完整性必须保持一致 |
原子性(Atomicity) | 事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。 |
隔离性(Isolation) | 是指多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离,不能相互影响。 |
持久性(Durability) | 指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响 |
2、事务的并发访问引发的三个问题(面试)
目标
能够理解并发访问的三个问题
讲解
事务在操作时的理想状态:多个事务之间互不影响,如果隔离级别设置不当就可能引发并发访问问题。
并发访问的问题 | 含义 |
---|---|
脏读 | 一个事务读取到了另一个事务中尚未提交的数据。最严重,杜绝发生。 |
不可重复读 | 一个事务中两次读取的数据内容不一致,要求的是一个事务中多次读取时数据是不一致的,这是事务update时引发的问题 |
幻读(虚读) | 一个事务内读取到了别的事务插入或者删除的数据,导致前后读取记录行数不同。这是insert或delete时引发的问题 |
1.脏读:指一个事务读取了另外一个事务未提交的数据。(非常危险)
脏读具体解释如下图所示:注意脏读的前提是没有事务的隔离性。
说明:事务a首先执行转账操作,然后事务a还没有提交数据的情况下,事务b读取了数据库的数据。紧接着事务a执行回滚操作,导致事务b读取的结果和数据库的实际数据是不一样的。
一个事务读取了另一个事务未提交的数据叫做脏读。
举例:
a 转账 给b 100,未提交
b 查询账户多了100
a 回滚
b 查询账户那100不见了。
一个事务读取了另一个事务没有提交的数据,非常严重,必须避免脏读。
2.不可重复读:在一个事务内多次读取表中的数据,多次读取的结果不同。
说明:事务b首先读取数据库的数据,然后事务a对数据修改并提交。之后事务b对数据库再次进行读取。这时发现在事务b中2次读取的结果不一致。
一个事务内读取了另一个事务提交的数据。这个叫做不可重复读。
不可重复读和脏读的区别:
脏读:强调的是读取了未提交的数据。
不可重复读:一个事务内2次读取,其中一次读取了另一个事务提交了的数据。
例如: 银行想查询A账户的余额,第一次查询的结果是200元,A向账户中又存了100元。此时,银行再次查询的结果变成了300元。两次查询的结果不一致,银行就会很困惑,以哪次为准。
和脏读不同的是:脏读读取的是前一事务未提交的数据,不可重复度 读取的是前一事务已提交的事务。
很多人认为这有啥好困惑的,肯定是以后面的结果为准了。我们需要考虑这样一种情况,查询A账户的余额,一个打印到控制台,一个输出到硬盘上,同一个事务中只是顺序不同,两次查询结果不一致,到底以哪个为准,你会不会困惑呢?
当前事务查询A账户的余额为100元,另外一个事务更新余额为300元并提交,导致当前事务使用同一查询结果却变成了300元。
3.幻读(虚读):一个事务内读取到了别的事务插入或者删除的数据,导致前后读取记录行数不同
说明:事务b首先读取数据的数量,然后事务a添加了一条数据,并且提交了。接着事务b再次读取了数据的数量。2次读取不一致。
同一个事务内,2次读取的数据的数量不一致,叫做幻读或者虚读。
虚读(幻读)和不可重复读的区别:
不可重复读:强调的是数据内容的不一致。另一个事务是update操作。
虚读(幻读):强调的数据的数量(记录数)的不一致。另一个事务是insert或者delete操作。
注意:
指在一个事务中 读取 另一个事务 插入或删除 数据记录,导致当前事务读取数据的记录数前后不一致。
一个事务读取另一个事务已经提交的数据,强调的是记录数的变化,常用sql类型为 insert和 delete。
小结
- 能够理解并发访问的三个问题
赃读:一个事务读取另一个事务还没有提交的数据,一定避免。
不可重复读:一个事务读取多次数据内容不一样,主要是update语句。事务已经提交了。 可以发生的。
幻读:一个事务读取多次数量不一样,主要是delete或者insert语句。事务已经提交了。可以发生的。
3、事务的隔离级别
目标
能够说出mysql的四种隔离级别
讲解
1、通过以上问题演示,我们发现如果不考虑事务的隔离性,会遇到脏读、不可重复读和虚读等问题。所以在数据库中我们要对上述三种问题进行解决。MySQL数据库规范规定了4种隔离级别,分别用于描述两个事务并发的所有情况。
上面的级别最低,下面的级别最高。“是”表示会出现这种问题,“否”表示不会出现这种问题。
级别 | 名字 | 隔离级别 | 脏读 | 不可重复读 | 幻读 | 数据库默认隔离级别 |
---|---|---|---|---|---|---|
1 | 读未提交 | read uncommitted | 是 | 是 | 是 | |
2 | 读已提交 | read committed | 否 | 是 | 是 | Oracle和SQL Server |
3 | 可重复读 | repeatable read | 否 | 否 | 是 | MySQL |
4 | 串行化 | serializable | 否 | 否 | 否 |
2、安全和性能对比
安全性:serializable > repeatable read > read committed > read uncommitted
性能 : serializable < repeatable read < read committed < read uncommitted
3、注意:其实三个问题,开发中最严重的问题就是脏读,这个问题一定要避免,而关于不可重复读和虚读其实只是感官上的错误,并不是逻辑上的错误。就是数据的时效性,所以这种问题并不属于很严重的错误。如果对于数据的时效性要求不是很高的情况下,我们是可以接受不可重复读和虚读的情况发生的。
小结
能够说出mysql的四种隔离级别
读未提交:read uncommitted
读已提交:read committed 可以避免脏读
可重复读:repeatable read mysql默认的,可以避免脏读 和不可重复读
串行化:serializable