• MySQL事务:特性、使用、并发事务问题和隔离级别


    什么是事务?

    在数据库中,事务是一组SQL操作,它们被视为一个单一的工作单元。事务必须同时成功或失败,以确保数据库的一致性。事务通常遵循ACID属性,即原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。

    1. 原子性(Atomicity)

    原子性要求事务中的所有操作要么全部成功,要么全部失败。如果在事务执行期间发生错误,所有已经执行的操作都会被撤销,数据库会回滚到事务开始前的状态。

    2. 一致性(Consistency)

    一致性确保事务执行后,数据库从一个一致状态转移到另一个一致状态。这意味着事务中的操作必须满足数据库的完整性约束。

    3. 隔离性(Isolation)

    隔离性定义了多个并发事务之间的互相影响程度。不同的隔离级别提供了不同的隔离程度,我们将在后面的部分详细讨论。

    4. 持久性(Durability)

    持久性确保一旦事务成功提交,其结果将永久保存在数据库中,即使系统崩溃也不会丢失。

    MySQL事务特性

    MySQL支持事务的特性,使其成为可靠的数据库管理系统。以下是一些关于MySQL事务的特性:

    自动提交

    默认情况下,MySQL启用自动提交(Auto Commit)模式。这意味着每个SQL语句都被视为一个独立的事务,当执行完成后自动提交到数据库。要启用显式事务,可以使用START TRANSACTION命令。

    事务控制命令

    MySQL提供了一系列用于控制事务的命令,包括BEGIN(或START TRANSACTION)、COMMITROLLBACKBEGINSTART TRANSACTION用于启动一个新事务,COMMIT用于提交事务,ROLLBACK用于回滚事务。

    保存点

    MySQL支持保存点(Savepoints),它允许在事务中创建一个标记点,以便在需要时回滚到该标记点。这对于实现更复杂的事务控制非常有用。

    MySQL事务的使用

    下面是一个简单的示例,演示了如何在MySQL中执行事务:

    START TRANSACTION;
    
    -- 在这里执行一系列SQL操作
    
    -- 如果一切正常,提交事务
    COMMIT;
    
    -- 如果发生错误,回滚事务
    ROLLBACK;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这个示例中,我们使用START TRANSACTION启动一个新事务,然后执行一系列SQL操作。如果一切正常,我们使用COMMIT提交事务,否则我们使用ROLLBACK回滚事务。

    并发事务问题

    在多用户环境中,同时执行多个事务可能导致一些并发问题。以下是一些常见的并发事务问题:

    1. 脏读(Dirty Read)

    脏读发生在一个事务读取了另一个事务未提交的数据。这可能导致不一致的结果。

    2. 不可重复读(Non-Repeatable Read)

    不可重复读发生在一个事务内的两次读取操作之间,另一个事务修改了数据,导致第二次读取返回不同的结果。

    3. 幻读(Phantom Read)

    幻读发生在一个事务内的两次查询之间,另一个事务插入或删除了数据,导致第二次查询返回不同的行数。

    隔离级别

    MySQL提供了不同的隔离级别来解决并发问题,包括:
    READ
    UNCOMMITTED
    READ COMMITTED
    REPEATABLE READ
    SERIALIZABLE
    不同的隔离级别提供不同的隔离程度和性能权衡。

    如果使用SERIALIZABLE隔离级别,事务之间的并发问题最少,但性能可能会受到一定影响。而使用READ COMMITTED级别可以提高性能,但并发问题可能更多。

    使用隔离级别解决并发问题

    假设有两个事务同时操作一个银行账户:

    -- 事务A
    START TRANSACTION;
    UPDATE accounts SET balance = balance - 100 WHERE account_id = 123;
    COMMIT;
    
    -- 事务B
    START TRANSACTION;
    UPDATE accounts SET balance = balance + 100 WHERE account_id = 123;
    COMMIT;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    如果不使用隔离级别,可能会发生并发问题,导致不一致的结果。但通过使用SERIALIZABLE隔离级别,可以确保事务A和事务B互斥执行,避免并发问题。

    -- 设置隔离级别为SERIALIZABLE
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
    
    -- 事务A
    START TRANSACTION;
    UPDATE accounts SET balance = balance - 100 WHERE account_id = 123;
    COMMIT;
    
    -- 事务B
    START TRANSACTION;
    UPDATE accounts SET balance = balance + 100 WHERE account_id = 123;
    COMMIT;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
  • 相关阅读:
    opencv 图像阈值
    UE4基础篇十二: 网络同步
    一些动态几何问题的流式算法
    Cobalt Strike(五)会话管理
    基于FPGA的交通信号灯设计
    VScode + PHPstudy + PHP Debug 调试PHP代码
    allegro提示错误(SPMHDB-225) The maximum number of text sizes has been reached.的解决
    4-ubuntu22.04-安装QT-5.15.2
    目标检测YOLO实战应用案例100讲-船舶目标检测及编队识别
    【夯实算法基础】 并查集
  • 原文地址:https://blog.csdn.net/weixin_50606361/article/details/133563844