mysql隔离级别产生的脏读,不可重复读,幻读问题

隔离级别:

    READ UNCOMMITTED  读未提交

    READ COMMITTED 读以提交

    REPEATABLE READ  可重复读

    SERIALIZABLE 串行化

隔离级别造成3个问题:

    脏读:一个事务处理过程里读取了另一个未提交的事务中的数据。

   不可重复读:一个事务内读取表中的某一行数据,多次读取结果不同。

   幻读:指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致

解决3个问题:

 

隔离级别 脏读 不可重复读 幻读
读未提交
读已提交 ×
可重复读 × ×
串行化 × × ×


 查询隔离级别的

SELECT @@global.tx_isolation;

设置隔离级别

set global transaction isolation level read committed;

 

案例演示:

读未提交(Read Uncommitted)

产生的问题:

读未提交 隔离级别下,一个事务会读到其他事务未提交的数据的,即存在脏读问题。第二个事务都还没commit到数据库呢,第一个事务就读到了。

mysql隔离级别产生的脏读,不可重复读,幻读问题

mysql隔离级别产生的脏读,不可重复读,幻读问题

读已提交(Read committed)

解决脏读:

将隔离级别从读未提交设置为读已提交级别

图一:为事务A

图二:为事务B

当事务B没有commit的时候,事务A前两次查都是正确的金额1000,当事务B进行了commit后,事务A查询的金额就是事务B修改后的金额,解决了脏读的问题

mysql隔离级别产生的脏读,不可重复读,幻读问题

mysql隔离级别产生的脏读,不可重复读,幻读问题

读已提交产生新的问题:

      事务A在读取金额为1000,当事务B修改了金额并且提交了事务修改,那么数据库现在金额变为1200,而事务A在次读取时金额为1200,那么事务A第一次读和第二次读的金额数据不一致,这个问题就是不可重复读的问题。

可重复读( Repeatable Read)

解决不可重复读

将隔离级别从读已提交设置为可重复读

图一:事务A

图二:事务B

在事务B提交了修改sql后,事务A在自己的事务中没有提交,两次读取都是相同的结果,解决了不可重复读的问题。

mysql隔离级别产生的脏读,不可重复读,幻读问题

mysql隔离级别产生的脏读,不可重复读,幻读问题

可重复读产生新的问题幻读:

        当我事务A没有提交事务。事务B修改了而且也提交了,事务A没有提交事务的情况下,读取的数据都是1000,解决了不可重复读的问题。

        但是现在事务B插入一条数据,并且提交了事务。现在事务A提交事务了,然后事务A在查询所有的数据时,发现多了一条数据,这就产生了幻读问题

mysql隔离级别产生的脏读,不可重复读,幻读问题

mysql隔离级别产生的脏读,不可重复读,幻读问题

串行化(SERIALIZABLE )

解决幻读问题

将隔离界别从可重复读设置为串行化

图一和图三:事务A

图二和图四:事务B

事务A开启事务,执行查询所有数据的sql,但是不提交事务。事务B开始事务,新增一条数据,但是这个时候新增不进去,被阻塞了。

当事务A提交事务后,事务B就可以新增成功。

因为隔离级别是串行化,当一个事务未执行完,其他事务必须等待第一个事务提交后才能进行事务操作,解决了幻读,不可重复读,脏读问题。

mysql隔离级别产生的脏读,不可重复读,幻读问题

mysql隔离级别产生的脏读,不可重复读,幻读问题

mysql隔离级别产生的脏读,不可重复读,幻读问题

mysql隔离级别产生的脏读,不可重复读,幻读问题