MySQL隔离级别详解带例子

  • READ-UNCOMMITTED(读取未提交):可以读取并发事务未提交(commit)的数据。可能会导致脏读、幻读或不可重复读。

    假如有两个客户端A,B;为A客户端开启事物,A客户端更改了一个表的一条数据,但是没有提交,这时候B客户端能够读取到这条A客户端修改了但未提交的数据,如果这个时候A客户端发现修改错了,回滚(rollback)一下,那么B客户端就读取到了一个错误的数据。这就是脏读现象,读取未提交是最低的隔离级别。 总结:事务B更新了一条记录,但是没有提交,此时事务A可以查询出未提交记录。

  • READ-COMMITTED(读取已提交):允许读取并发事务已经提交的数据。可以阻止脏读,但是幻读或不可重复读仍有可能发生。

    假如有两个客户端A,B;为A客户端开启事物,A客户端更改了一个表的一条数据,但是没有提交,这时候B客户端能够读取到的是A客户端修改前的数据,如果这个时候A客户端发现修改没问题,提交(commit)一下,那B客户端再次读取这条数据,就是修改后的数据了。读取已提交隔离级别解决了脏读的问题,但是出现了不可重复读的问题,即事务B在两次查询的数据不一致,因为在两次查询之间事务A更新了一条数据。读取已提交隔离级别只允许读取已提交的记录,但不要求可重复读。

  • REPEATABLE-READ(可重复读):对同⼀字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改。可以防止脏读和不可重复读,但幻读仍有可能发生。

    幻读:对于两个事务Session A、Session B,Session A 从一个表中读取了一个字段,然后 Session B 在该表中 插 入了一些新的行,并提交。之后,如果 Session A 再次读取同一个表,就会多出几行,那就意味着发生了幻读。

    注:在重复读下情况下,存相同的数据时能发现主键存在,不能插入,但是查询的时候就是查不到。(想存存不上,想读读不到)

    假如有两个客户端A,B;为B客户端开启事物(这个时候B客户端的所能读取的数据内容就定格在这一时间点)然后为A客户端开启事物,A客户端更改了一个表的一条数据,不管A事物是否提交,B客户端在没提交事物前都不能读取到A客户端对数据所做的修改。 可重复读隔离级别只允许读取已提交记录,而且在一个事务两次读取一个记录期间,其他事务不能更新该记录。但该事务不要求与其他事务可串行化。例如,当一个事务可以找到由一个已提交事务更新的记录,但是可能产生幻读问题(注意是可能,因为数据库对隔离级别的实现有所差别)。像以上的实验,就没有出现数据幻读的问题。

  • SERIALIZABLE(可串行化): 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰。该级别可以防止脏读、不可重复读以及幻读。

    假如有两个客户端A,B;为B开启事物,然后执行查询全表数据,这个时候B占有着全部数据,如果A想要修改数据就必须等B事物提交。此外,A查询不受影响。 serializable完全锁定字段,直到前一个事务完成并解除锁定为止 。是完整的隔离级别,会锁定对应的数据表格,因而会有效率的问题。

猜你喜欢

转载自blog.csdn.net/m0_57545353/article/details/124996169