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