一、事务的4大特征(ACID)
1、原子性(Atomicity)
原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚。
2、一致性(Consistency)
一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性。
3、隔离性(Isolation)
隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。
4、持久性(Durability)
持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。
二、 脏读、不可重复读、幻读
以上介绍完事务的四大特性(简称ACID),现在重点来说明下事务的隔离性,当多个线程都开启事务操作数据库中的数据时,数据库系统要能进行隔离操作,以保证各个线程获取数据的准确性,在介绍数据库提供的各种隔离级别之前,我们先看看如果不考虑事务的隔离性,会发生的几种问题。
1、脏读(读未提交)
事务A读取到了事务B已经修改但尚未提交的数据。(修改数据)
对于两个事务T1,T2,T1读取了已经被T2更新但还没有被提交的字段之后,若T2回滚,T1读取的内容就是临时且无效的
2、不可重复读(读已经提交)
事务A内部的相同查询语句在不同时刻读出的结果不一致,不符合隔离性。
不可重复读:对于两个事务T1,T2,T1读取了一个字段,然后T2更新了该字段之后,T1在此读取同一个字段,值就不同了。
3、虚读(幻读)
事务A读取到了事务B提交的新增数据,不符合隔离性。(还是读未提交,和脏读不同的是添加和删除数据)
幻读:对于两个事务T1,T2,T1从一个表中读取了一个字段,然后T2在该表中插入了一个新的行之后,如果T1再次读取同一个表,就会多出几行。
三、四种隔离级别
列出四种隔离级别下,是否会发生响应的脏读、不可重复读、幻读。
级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交RU(read-uncommitted) | 是 | 是 | 是 |
读已提交RC(read-committed) | 否 | 是 | 是 |
可重复读RR(repeatable-read) | 否 | 否 | 是 |
串行化(serializable) | 否 | 否 | 否 |
① Read uncommitted (读未提交):最低级别,任何情况都无法保证。
② Read committed (读已提交):可避免脏读的发生。
③Repeatable read (可重复读):可避免脏读、不可重复读的发生。
④ Serializable (串行化):可避免脏读、不可重复读、幻读的发生。
参考:https://www.cnblogs.com/tartis/category/1029400.html
四、MySQL常见的三种存储引擎(InnoDB、MyISAM、MEMORY)
参考:https://www.cnblogs.com/tartis/p/9365903.html
总结:
1、mysql的默认存储引擎是InnoDB。
2、InnoDB引擎的隔离级别是可重复读RR(repeatable-read)。
3、可重复读RR(repeatable-read) 解决了脏读、不可重复读,但是没有解决幻读。
所以mysql 默认的隔离级别是可重复读RR,从上面的表中我们知道,RR的隔离级别并未解决幻读问题,但是许多人说mysql 解决了幻读问题,这是怎么回事呢?这就需要我们知道mysql的MVCC机制。
针对这个问题可以参考这篇文章
MySQL Innodb RR隔离级别下到底是不是解决了幻读