1

很多PHP开发者在面试的时候遇到这个问题都会卡壳。这是因为理解得不够透彻,今天让我带领大家梳理一下mysql事务隔离级别

数据库有四种隔离级别,分别是Read uncommitted,Read committed ,Repeatable read,Serializable (读未提交,读提交,可重复读,序列化)

  • Read uncommitted 读未提交,就是一个事务可以读取另一个未提交事务的数据。

例如:A原来的账号是100元,然后B转账100给A,此时B的事务未提交,A读到自己的账号是200,但是后来B发现不对劲回滚了事务,
那么最终这个A的账号还是100元。A其实看到的是B还未提交事务时的数据。这就是脏读。

那么怎么解决脏读呢?Read committed!读提交,能解决脏读问题。


  • Read committed 读提交,就是一个事务要等另一个事务提交后才能读取数据。

例如:A读到钱是100块,B在一个事务中转了100后撤销,在这个过程中,A是读不到B的数据变化的,所以不会存在脏读问题,然后A开开心心去买个东西,结果就发现账号没钱了,原来是B又开启了一个事务提前花光了A的所有钱,轮到A的事务已经是没钱了。

但在这个事例中,出现了一个事务范围内两个相同的查询却返回了不同数据,数据发现了变化(也就是不可以重复读)这就是不可重复读

那么这个问题,怎么解决呢?Repeatable read !可重复读


  • Repeatable read 可重复读 就是在开始读取数据(事务开启)时,不再允许修改操作

例如:A读到钱是100块,然后他去消费,在此期间,B是无法去修改A的帐号的钱,也就是在B的事务中不能去修改A的数据了。A的数据是可重复读
,也就是从头到尾读到的数据是相同的。

分析:重复读可以解决不可重复读的问题。写到这里,应该明白的一点就是,不可重复读对应的是修改,即UPDATE操作。
但是可能还会有幻读问题。因为幻读问题对应的是插入INSERT操作,而不是UPDATE操作。

什么时候会出现幻读?

事例:A某一天去消费,花了50元,然后B去查看A的消费记录,看到确实是花了50元,就在这个时候,A又花了50,即新增INSERT了一条消费记录并提交。
当B打印A的消费记录清单时(B事务提交),发现花了100元,似乎出现了幻觉,这就是幻读。

那怎么解决幻读问题?Serializable!


Serializable 序列化

Serializable 是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。
但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。

值得一提的是:大多数数据库默认的事务隔离级别是Read committed,比如Sql Server , Oracle。
Mysql的默认隔离级别是Repeatable read。

lzhui
12 声望1 粉丝

PHP工程师,半全栈开发。时刻保持一颗谦卑的心。