人生的座右铭:生活的只有一种病,叫穷病,学习是最能变现的路径之一,加油吧!
数据库:
Mysql版本:5.7.20-log
一.先说一下数据库四种隔离级别:原子性、一致性、隔离型、持久性(ACID)
1.原子性(Atomicity):原子性是指一个事务中的操作,要么全部成功,要么全部失败,成功事务就会提交,失败就回滚到事务开始 前的状态。
2.一致性(Consistency):一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。(都是拿转账举例子:A账户和B账户之间相互转账,无论如何操作,A、B账户的总金额都必须是不变的。)
3.隔离性(Isolation):隔离性是当多个用户 并发的 访问数据库时,如果操作同一张表,数据库则为每一个用户都开启一个事务,且事务之间互不干扰,也就是说事务之间的并发是隔离的。再举个栗子,现有两个并发的事务T1和T2,T1要么在T2开始前执行,要么在T2结束后执行,如果T1先执行,那T2就在T1结束后在执行。关于数据的隔离性级别,将在后文讲到。
4.持久性(Durability):持久性就是指如果事务一旦被提交,数据库中数据的改变就是永久性的,即使断电或者宕机的情况下,也不会丢失提交的事务操作。
延伸一下:
我们操作数据库,无非是读(select),和更新(update),或者写入(inset)
在并发的访问数据库中,一个用户的事务,不应该给其他用户的事务干扰,多并发的事务要相互隔离。
如果不考虑隔离性,会有四种现象,请让我徐徐道来
1.脏读(针对未提交的数据)
(脏读是指在一个事务读取了另一个未提交的事务中的数据)
2.不可重复读(针对修改操作)
(不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了,导致了同一事务中查询到的结果不一样。)
注释:不可重复读和脏读的区别:脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据
3.幻读
(幻读是一个事务在读取数据时,另一个事务插入了新数据,读取数据的时候会多读出数据,产生幻觉一样,这就是幻读)
注释:幻读和不可重复读都是读取了另一条已经提交的事务(脏读不是这样),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)
二.MySQL数据库的四种事务隔离级别
1.读未提交(Read Uncommitted):在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)
2.读并提交(Read Committed):这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。 这种隔离级别 也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果
3.可重复读(Repeatable Read):这是MySQL的默认事务隔离级别,同一事务的多个实例在并发读取数据时,会看到同样的数据。不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。 简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。
4.可串行化(Serializable):这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争
以上四种隔离级别最高的是Serializable级别,最低的是Read uncommitted级别,当然级别越高,执行效率就越低。
像Serializable这样的级别,就是以锁表的方式(类似于Java多线程中的锁)使得其他的线程只能在锁外等待,所以平时选用何种隔离级别应该根据实际情况。
在MySQL数据库中默认的隔离级别为Repeatable read (可重复读)
在MySQL数据库中查看当前事务的隔离级别: select @@tx_isolation;
InnoDB MVCC 机制:
MVCC(Multiversion Concurrency Control)中文全称:多版本并发控制
写的博客好的链接:https://www.codercto.com/a/88775.html 还没写完,先看着观客们