mysql 重复读自己事务中可以看到新插入数据

发布于:2025-04-10 ⋅ 阅读:(29) ⋅ 点赞:(0)

推荐好文  吃透MySQL(六):事务详细介绍 地址转发https://blog.csdn.net/u013277209/article/details/113585022

开启客户端  mysql  -u  账号名 -p

 输入密码

在一个 事务中

mysql> set session transaction isolation level repeatable read;

Query OK, 0 rows affected (0.00 sec)

mysql> set autocommit = 0;

Query OK, 0 rows affected (0.00 sec)

mysql> start transaction;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from test;

      +----+ | id | +----+ | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | | 7 | | 10 | | 11 | | 12 | +----+ 10

      rows in set (0.00 sec)

mysql> insert into test values(13);

Query OK, 1 row affected (0.00 sec)

mysql> select * from test; +----+ | id | +----+ | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | | 7 | | 10 | | 11 | | 12 | | 13 | +----+ 解释一下没有提交为啥能看到新插入数据

在你的 MySQL 会话中,你观察到在未提交事务的情况下能够看到新插入的数据,这实际上是在预期之内的行为。让我们详细解释一下:

解释

  1. 当前会话的可见性
    • 在一个 MySQL 会话中,当你执行 INSERT 操作后,即使事务尚未提交,该会话中的后续查询仍然可以看到这个新插入的数据。这是因为 MySQL 允许当前会话看到它自己所做的未提交更改。
  2. 事务隔离级别的定义
    • 事务隔离级别(如 REPEATABLE READ)主要控制的是不同事务之间的可见性。它定义了一个事务在何时可以看到其他事务的更改。
    • REPEATABLE READ 确保在一个事务中,多次执行相同的查询会返回相同的结果集,除非查询本身涉及到了当前事务中的修改。这意味着其他事务的未提交更改对当前事务是不可见的,但当前事务自己的未提交更改是可见的。
  3. autocommit 的影响
    • 你已经通过 SET autocommit = 0; 关闭了自动提交,这意味着每个 INSERTUPDATE 或 DELETE 操作不会自动提交,而是需要显式地执行 COMMIT;

为什么能看到未提交的数据?

  • 当前事务的上下文:在同一个事务中,MySQL 会维护一个当前事务的上下文,其中包括该事务所做的所有更改(即使这些更改尚未提交)。因此,当你执行 SELECT 查询时,MySQL 会返回当前事务上下文中的所有数据,包括未提交的更改。

示例解释

在你的示例中:

  1. 你开始了一个事务。
  2. 你执行了一个 SELECT 查询,看到了表中的初始数据。
  3. 你插入了一条新记录。
  4. 你再次执行 SELECT 查询,这次看到了包括新插入记录在内的所有数据。

这是因为在同一个事务中,MySQL 允许你看到自己的未提交更改。

注意事项

  • 其他会话的可见性:如果另一个会话同时连接到数据库并执行相同的 SELECT 查询,它将看不到你未提交的更改,除非它也处于相同的事务上下文中(这在实际中是不可能的,因为每个会话都有自己的事务上下文)。
  • 提交事务:当你执行 COMMIT; 时,你的更改将被永久保存到数据库中,并且对其他会话可见。
  • 回滚事务:如果你执行 ROLLBACK;,你的更改将被撤销,并且不会对其他会话可见。

通过理解这些概念,你可以更好地控制事务的行为,并确保数据的一致性和完整性。