首页 > 数据库 >数据库事务中的脏读、不可重复读和幻读

数据库事务中的脏读、不可重复读和幻读

时间:2025-01-20 09:56:53浏览次数:3  
标签:事务 隔离 幻读 数据库 T1 READ 脏读 提交 级别

在数据库系统中,事务的隔离级别是一个非常重要的概念。它决定了事务在执行过程中如何与其他事务进行交互,以及在不同事务之间如何共享数据。事务的隔离级别越高,数据的一致性越好,但并发性能可能会降低。

脏读(Dirty Read)

脏读是指一个事务读取到另一个事务未提交的数据。如果该未提交事务最终被回滚,那么第一个事务读取的数据就是不一致的(脏的)。

示例: 假设有两个事务T1和T2,当前事务的隔离级别设置为READ UNCOMMITTED(读未提交)。T1从表t中读取数据,表内原始有一条记录a。然后T2插入了一条新记录b,但未提交。此时,T1再次读取表t,发现有两条记录a和b。如果T2回滚,那么T1读取到的数据就是无效的。

解决方法:

  • 将事务隔离级别提高到READ COMMITTED(读已提交)或更高。

不可重复读(Non-repeatable Read)

不可重复读是指在一个事务内,多次读取同一数据时,由于其他事务的提交,读取的结果不同。

示例: 假设有两个事务T1和T2,当前事务的隔离级别设置为READ COMMITTED(读已提交)。T1读取表t内的数据,表内原始有一条记录a=100。然后T2修改并提交了这条记录,将a改为50。此时,T1再次读取表t,发现记录a的值变为50,与之前读取的结果不同。

解决方法:

  • 将事务隔离级别提高到REPEATABLE READ(可重复读)或更高。

幻读(Phantom Read)

幻读是指一个事务内,针对同一查询条件的多次操作(如查询记录数),因其他事务插入或删除数据导致结果数量不一致。

示例: 假设有两个事务T1和T2,当前事务的隔离级别设置为READ COMMITTED(读已提交)。T1查询表t内a>=100的记录数,发现有5条记录。然后T2插入了一条新记录111,并提交。此时,T1再次查询表t内a>=100的记录数,发现有6条记录。

解决方法:

  • 提升隔离级别到SERIALIZABLE(串行化)。

  • REPEATABLE READ(可重复读)下,使用Next-Key Lock(记录锁+间隙锁)防止幻读。

MySQL中的隔离级别

MySQL提供了四种隔离级别,分别是:

  1. READ UNCOMMITTED(读未提交)

  2. READ COMMITTED(读已提交)

  3. REPEATABLE READ(可重复读)

  4. SERIALIZABLE(串行化)

每种隔离级别解决的问题如下:

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

解决幻读的方法

  1. 事务隔离级别设置为SERIALIZABLE

  2. 在可重复读的事务级别下,给事务操作的这张表加表级锁。

  3. 在可重复读的事务级别下,给事务操作的这张表加Next-Key Lock锁(Record Lock + Gap Lock)。

InnoDB解决幻读

MySQL InnoDB引擎的默认隔离级别虽然是REPEATABLE READ(可重复读),它很大程度上避免了幻读问题:

  • 针对普通快照读(SELECT ... FROM ...):通过MVCC方式解决。

  • 针对当前读(SELECT ... FOR UPDATE):通过Next-Key Lock方式解决了幻读。

隔离级别的实现

  1. 读未提交:直接读取最新的数据。

  2. 串行化:加锁控制并行访问。

  3. 读已提交和读未提交:借助查询生成的ReadView实现。

    • 读已提交是在每个语句执行之前都会重新生成一个ReadView

    • 可重复读隔离级别是在启动事务时生成一个ReadView

标签:事务,隔离,幻读,数据库,T1,READ,脏读,提交,级别
From: https://blog.csdn.net/m0_73355421/article/details/145255176

相关文章

  • 高级java每日一道面试题-2025年01月20日-数据库篇-并发事务带来哪些问题?
    如果有遗漏,评论区告诉我进行补充面试官:并发事务带来哪些问题?我回答:并发事务带来的主要问题在多用户环境中,多个事务可能同时对数据库进行读写操作,这可能导致以下几种常见的并发问题:1.脏读(DirtyRead)定义:当一个事务能够读取到另一个未提交事务的数据修改时,称为......
  • 数据库基础——mysql数据库
    一、数据库简介    数据库:数据库是一个按数据结构来存储和管理数据的计算机软件系统。简单来说,数据库是用来存放数据的。    常见数据库及端口mysql(3306):关系型数据库  mssal(1433)  oracle(1521)  db2(9500)  postgresql(5432)       ......
  • 数据库密码安全修改:保护织梦网站账户安全的黄金法则
    严格权限控制:仅授予最小化权限给真正需要访问数据库的人,避免不必要的暴露风险。定期清理过期账号,防止非法入侵。日志记录完善:开启详细的日志记录功能,记录下每一次登录、退出、增删改查等关键事件。一旦发现问题可以迅速定位原因并采取相应措施。步骤描述备份数据优先......
  • 请问数据库管理平台无法打开,如何排查和解决?
    您好!当您遇到数据库管理平台无法打开的问题时,可能是由于多种原因引起的,包括服务器配置、网络连接、权限设置等。为了帮助您更好地理解和解决这个问题,以下是几个可能的原因及相应的解决方案:检查服务器状态首先,请确认服务器是否正常运行。您可以登录到服务器控制面板(如宝塔面板),查......
  • 如何将MySQL数据库版本升级到5.7并确保网站正常运行?
    在云服务器上将MySQL数据库版本从较低版本升级到5.7是一项需要谨慎操作的任务,以确保网站的正常运行。以下是详细的步骤和注意事项:一、备份现有数据备份数据库:在进行任何升级操作之前,务必对现有数据库进行全面备份。可以使用命令行工具或图形界面工具(如phpMyAdmin)进行备份。......
  • 如何解决WordPress打开网页时出现“建立数据库连接时出错”的问题?
    常见原因数据库配置文件错误:wp-config.php文件中的数据库配置信息不正确。MySQL数据库服务问题:MySQL数据库服务未启动或数据库账号密码错误。网络连接问题:如果使用外部数据库,可能需要检查网络连接和端口配置。解决方法方法一:检查数据库配置文件打开wp-config.php文件:......
  • 解决数据库导入失败及字符编码不一致的问题
    当您在导入SQL文件时遇到500错误,并且需要确认数据库编码是否为UTF-8时,可以按照以下步骤进行排查和解决:备份现有数据:在执行任何数据库操作之前,请确保已经对现有数据进行了完整备份。可以通过导出当前数据库结构和数据的方式创建备份文件,以防止意外丢失重要信息。检查SQL......
  • 【数据库】MySQL数据库之约束与多表查询
    约束1.概述概念:约束是作用于表中字段上的规则,用于限制存储在表中的数据目的:保证数据库中数据的正确性、有效性,完整性和一致性分类:注意:约束是作用于表中字段上的,可以在创建表/修改表的时候添加约束2.外键约束概念外键用来让两张表的数据之间建立连接,从而保证数据的一致性......
  • 如何修改zblog的数据库连接信息以适应新的主机环境?
    当您需要将zblog迁移到新的主机环境时,必须更新其数据库连接信息,以确保网站能够正常运行。以下是详细的修改步骤和注意事项,帮助您顺利完成这一过程:确定配置文件位置:zblog的数据库配置文件位于zb_users/c_option.php。该文件包含了所有与数据库连接相关的配置项。备份现有配......
  • 如何安全地强制卸载宝塔面板中的数据库?
    在某些情况下,您可能需要在宝塔面板中强制卸载数据库,例如更换数据库版本或清理不再使用的数据库实例。然而,直接卸载可能会遇到一些问题,特别是当数据库存在问题无法启动时。以下是安全且有效的强制卸载方法,同时确保数据安全和系统稳定性:备份数据库:在进行任何操作之前,务必先备份......