为什么MySQL Workbench在设置了“READ UNCOMMITTED”隔离级别后不显示未提交的更改?

k5ifujac  于 2023-02-18  发布在  Mysql
关注(0)|答案(1)|浏览(198)

我有一个PHP脚本,我试图测试。这个脚本执行数百个MySQL查询。
为了进行测试,我一直在使用VSCode中的XDebug逐步执行脚本,同时使用MySQL Workbench临时选择数据,以了解特定查询之前和之后的数据状态(但在脚本执行期间)。
我想开始使用transactions,这样我就可以在每次测试完成后更轻松地将数据库回滚到测试前的状态。但是,我发现即使使用SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED,我也无法使用MySql Workbench查看未提交的数据。这违背了测试的全部目的,即能够在测试期间 * 临时查看数据。*

正在发生的情况示例:

代码执行前MySQL Workbench访问的test表:
| 身份证|
| - ------|
| 二十一|
| 四十二|
使用XDebug单步调试PHP代码(使用PDO访问DB):

$pfConn = (new DbConn('test'))->connect();
$sql = "SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED";
$stmt = $pfConn->prepare($sql);
$stmt->execute();
$sql = "SELECT @@tx_isolation"; //just confirming the isolation level
$stmt = $pfConn->prepare($sql);
$stmt->execute();
$res = $stmt->fetchColumn(); //$res = "READ_UNCOMMITTED"
$pfConn->beginTransaction();
$sql = "INSERT INTO test (id) VALUES (63)";
$stmt = $pfConn->prepare($sql);
$stmt->execute();

此时,我再次使用MySQL Workbench访问test表:
| 身份证|
| - ------|
| 二十一|
| 四十二|
尽管执行了READ_UNCOMMITTED操作,MySQL Workbench仍看不到未提交值63。
现在,我继续单步执行PHP代码以提交值:

$pfConn->commit();

现在,当我使用MySQL Workbench访问我的表时,我看到了正确插入(现在已提交)的数据:
| 身份证|
| - ------|
| 二十一|
| 四十二|
| 六十三|
上述行为不仅适用于插入,也适用于更新。
应该注意的是,如果我改为使用SETGLOBALTRANSACTION ISOLATION LEVEL READ UNCOMMITTED,MySQL Workbench***将能够看到未提交的更新。这与我所希望的方向相反。实际上,我甚至不希望使用像SESSION这样广泛的隔离级别,而只希望使用特定于事务的隔离级别。我不希望出现无意的“脏读”发生。
如果要我猜的话,我认为我对两个独立的连接如何与事务隔离级别交互有一个根本性的误解,但是我通过搜索来了解这个问题的努力一直没有结果,因此我在这里问这个问题。
此外,虽然我主要是问为什么会发生这种情况,以及我可以做些什么来使这种测试工作,但如果有人对如何更好地进行这种测试有任何想法,我也会非常感激。

wribegjk

wribegjk1#

您需要在MySQL Workbench会话上将tx_isolation设置为READ UNCOMMITTED,而不是在PHP代码中的会话上。
下面是在两个窗口中使用mysql客户端的演示:

窗口1:

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into user set name = 'bill', created_at = now();
Query OK, 1 row affected (0.00 sec)

我没有更改此会话的隔离级别。
先不要提交该事务。

窗口2:

mysql> select * from user;
Empty set (0.00 sec)

如预期。使用默认事务隔离级别时,此会话无法看到未提交的更改。
现在更改此客户端的隔离级别,然后重试。

mysql> set transaction_isolation='READ-UNCOMMITTED';
Query OK, 0 rows affected (0.00 sec)

mysql> select * from user;
+----+------+---------------------+
| id | name | created_at          |
+----+------+---------------------+
|  1 | bill | 2023-02-17 14:50:13 |
+----+------+---------------------+
1 row in set (0.00 sec)

重要的是希望查询未提交数据的客户机的隔离级别。
我想用MySQL Workbench做一个演示,但是当我运行任何查询时,当前版本(8.0.32)似乎会崩溃。这已经被报告为bug:https://bugs.mysql.com/bug.php?id=109671
我一般不使用MySQL Workbench,它的bug太多了,对工作的阻碍往往大于帮助。

相关问题