转载:SQL隔离级别

转自 https://blog.csdn.net/blakeFez/article/details/48416127

什么是SQL的隔离级别呢?举个例子来说吧。 
事例1、 
假设有用户A和用户B,他们对同一张innodb表进行如下操作: 
①、同时开启一个事务: 
②、用户A向表中插入一条数据。 
③、用户B查询表中的数据。 
④、同时提交事务。

那么,当用户A插入数据之后,用户B再去表中查询数据时,用户A刚才插入的那条数据对用户B这次的查询是否可见,便成为隔离级别。

SQL标准定义了四个隔离级别:

一、READ UNCOMMITTED(读取未提交内容) 
在这个隔离级别下,当在事务a中修改数据后,虽然事务a还没有提交,但其他事务也能读取到事务a中修改的内容。就比如上面说的那个列子,如果是在这个隔离级别下,用户B就能读取到用户A插入的那条数据。

在这个隔离级别下,最容易出现“脏读”这个问题。比如事例1中,当用户A插入数据后,提交事务的时候出现问题,然后事务回滚,把用户A插入的那条数据删除,但用户B却读到了那条数据。

二、READ COMMITTED(读取提交内容) 
在这个隔离级别下,当事务a中修改数据后,只要事务a还没有提交,就不能被其他事务读取到修改的内容。但在一个事务中,任何一次查询,都是获取已经提交事务的所有变化。 
比如以下例子: 
事例2、 
①、用户A开启一个事务。 
②、用户B向表1中插入一条数据x,提交事务。 
③、用户A查询表1中的数据。 
④、用户B向表1中插入一条数据y,提交事务。 
⑤、用户A查询表1中的数据。 
⑥、用户A提交事务。 
那么,对用户A的这次事务来说,前后两次的查询结果是不同的。这也是这个隔离级别的问题所在。

三、REPEATABLE READ(可重读) 
这个隔离级别就是为了解决上一个隔离级别而生的。在这个隔离级别下,在一个事务中的查询,只能读取到事务开始时,表中的数据。比如事例2中,在用户A开启事务的过程中,用户B向表1中插入了两条数据,但在这一隔离级别下,用户A的两次查询都读取不到用户B插入的数据。

然而,这个隔离级别就会出现“幻读”的问题。比如如下列子: 
事例 3、 
①、用户A开启一个事务。 
②、用户B向表1中插入一条数据x,提交事务。 
③、用户A查询表1中的数据,判断是否存在数据x。 
④、用户A发现表1中没有数据x,然后也插入数据x。 
⑥、用户A提交事务。 
这时候,如果表中有唯一建,那么用户A插入数据x时,就会报错。这里,就把第三步,用户A查询表中数据,判断是否存在数据x的结果称为“幻读”。

四、SERIALIZABLE(可串行化) 
这个隔离级别是最高的隔离级别,用于解决幻读问题。在这个隔离级别下,它会强制的对事务进行排序,使事务之前不可能冲突,从而解决幻读问题。所谓的排序,是指:为每个事务所读取的行加上锁。在这一级别下,会造成大量的超时现象和锁竞争。


阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页