数据库的隔离级别以及脏读,不可重复读和幻读

2022-07-31,,,

数据库隔离性:

  • 多个事务并发执行时,事务之间不能相互干扰。(其本质就是线程安全的问题).
    隔离性和并发性其实是相悖的,隔离是为了保证数据的准确,并发是为了保证事务的执行效率。如果多个事务之间隔离性越强,并发程度就越低,效率就越低;多个事务之间隔离性越弱,并发程度就越高,效率就越高。但是在不同的场景下,对于数据的准确性要求不一样,就可以在满足数据准确要求的前提下尽可能的提高并发程度。

并发执行事务时可能产生的恶果(脏读,不可重复读,幻读)

  • 脏读

  • 事务中的修改,即使没有提交,对其他事务也都是可见的。其他事务可以读取没有提交的数据并使用,这就是脏读。
    例如:在线文档编辑,一个人正在编写文档,其他人仍可以查看这个文档,然后获取到第一个人编写的信息,在此之后第一个人修改了他写入的信息并提交,那么读取的人就读到了脏数据,这也就是脏读。

  • 解决办法就是给写操作加锁,第一个人修改的时候第二人尝试读取数据就会阻塞,直到第一个人提交完数据,第二个人才可以读取。
    引入写加锁,事务的并发程度降低,效率变低,隔离性提高

  • 不可重复读

  • 是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的数据可能是不一样的。
    因为一个事务从开始直到提交之前,所做的任何修改对其他事务都是不可见的,所以两次查询会得到不同的结果。
    例如:还是文档编辑但不是在线的,A两次去读这个文档,在这之间,B重新写了这个文档,就会导致A两次读取文档获取到的信息不相同。

  • 解决办法就是给读加锁,在A读取这个文档的时候,B不能重新编辑。 引入读加锁,事务的并发程度更低,效率也更低,隔离性又提高一个阶层。

  • 幻读
    当某个事务在读取某个范围内的记录时,另外一个事务又在范围内插入了新的记录,当之前的事务再次读取该范围的数据,发现新增了记录,就跟产生了幻觉一样。
    例如:事务1查询id<10的记录时,返回了4条记录,接着事务2插入了一条id为3的记录,并提交。接着事务1查询id<10的记录时,返回了5条记录,新增了一条。

  • 解决办法就是严格的串行化执行,强制事务串行执行,避免了前面说的幻读的问题。

数据库的隔离级别
1.Read uncommitted (未提交读)

  • 允许事务读取未提交的数据,隔离程度低,并发程度高,但会有脏读问题

2.Read committed (提交读)

  • 不可读取未提交的写数据,允许写并发。隔离程度提高,并发性降低,解决了脏读但是会出现不可重复读的问题。

3.Repeatable read (可重复读)

  • MYSQL的默认事务隔离级别。该级别解决了不可重复读的问题,但是无法解决幻读的问题。隔离性提高,并发程度又降低。

4.Serializable (串行化)

  • 这是最高的隔离级别。强制事务串行执行,避免了幻读的问题。它会在读取的每一行数据上都加锁,所以可能导致大量的超时和锁争用的问题,实际中很少使用。
隔离级别 脏读可能性 不可重复读可能性 幻读可能性
Read uncommitted
Read committed
Repeatable read
Serializable

本文地址:https://blog.csdn.net/zyrzl/article/details/107656914

《数据库的隔离级别以及脏读,不可重复读和幻读.doc》

下载本文的Word格式文档,以方便收藏与打印。