MySQL事务状态判断

MySQL事务状态判断

前置

MySQL的默认隔离级别是: 可重复读(REPEATABLE READ)

可重复读隔离级别下,事务中的SELECT操作会看到快照数据,也就是事务开始时刻的数据状态。此隔离级别可以防止脏读和不可重复读,但可能会有幻读的问题出现。

问题描述

表结构

create table djj
(
    name    varchar(100) null,
    account int          null
);

表数据

在事务开始前,表djj​中有一条记录:

name account
djj 50

脚本A和脚本B

脚本A和脚本B都是对表djj​进行的操作。脚本A将账户余额更新为40,而脚本B将账户余额更新为60。

操作流程

按照给定的操作流程,两个事务交错执行,如下:

flowchart TD ATXStart[A.TX Start] --> BTXStart[B.TX Start] BTXStart --> Aa[A.a] Aa --> Ab[A.b] Ab --> Ba[B.a] Ba --> Bb[B.b] Bb --> Ac[A.c] Ac --> ATXCommit[A.TX Commit] ATXCommit --> Bc[B.c] Bc --> BTXCommit[B.TX Commit]
  1. A.a : 查找到的结果是 50
  2. A.b : 成功执行更新,账户余额变更为40
  3. B.a : 查找到的结果是 50(因为B事务的快照是在A事务提交前的状态)
  4. B.b : 此时因为A事务尚未提交,B事务的更新操作会等待A事务释放行锁
  5. A.c : 此时的结果是40(A事务可以看到自己的更新)
  6. A.TX Commit: A事务提交,释放行锁
  7. B.b : 执行成功,账户余额更新为60(B事务现在可以获取先前被A事务持有的行锁)
  8. B.c : 结果为60(B事务在提交前看到的是自己的更新)

注意

  1. 在可重复读隔离级别下,读操作不会看到其他未提交事务的更改(防止脏读),但写操作会等待其他事务释放锁(行锁或表锁),然后写入最新的数据。
  2. 死锁通常发生在多个事务试图以不同的顺序锁定资源时,例如,当两个事务都试图更新同一行数据,或者在使用SELECT FOR UPDATE​时。在这种情况下,MySQL会自动检测死锁并回滚一个事务来解决问题。
posted @ 2024-04-12 22:38  pDJJq  阅读(8)  评论(0编辑  收藏  举报