Fra*_*k J 5 mysql innodb transactions isolation-level
也许你可以在这里为我阐明一些事情:
数据库 = MySQL 5.7
存储引擎:InnoDB
隔离级别:可重复读
下表:
---------------
| MyTable |
---------------
| PK | Concur |
---------------
| 3 | 2 |
---------------
Run Code Online (Sandbox Code Playgroud)
我此时没有进行任何交易,我选择此记录,例如
SELECT * FROM MyTable WHERE PK = 3
并将结果存储在我的程序中。
我现在开始一个数据库事务。在我的事务开始后,外部进程Concur将 = 3 的记录从 2 增加到 3。PK
我还没有再次从我的交易中的该表中读取内容。
我从交易内部发出以下查询:
UPDATE MyTable SET Concur = 3 WHERE PK = 3 AND Concur = 2
这将成功0 records affected。很明显,它会根据我的交易开始后更改的数据进行评估。仍在交易中我随后查询:
SELECT * FROM MyTable WHERE PK = 3
这将返回记录,其中PK = 3 and Concur = 2包含交易之前的值。
为什么行为SELECT和UPDATE ... WHERE行为不同,我错过了什么?
我本以为该UPDATE ... WHERE语句要么直接失败,而不是成功,影响 0 条记录,要么成功,影响 1 条记录,然后在之后崩溃COMMIT,但不是这种混合和匹配。
这里有什么见解吗?
https://dev.mysql.com/doc/refman/8.0/en/innodb-concient-read.html
一致读取意味着 InnoDB 使用多版本控制向查询提供数据库在某个时间点的快照。该查询会看到该时间点之前提交的事务所做的更改,而不会看到稍后或未提交的事务所做的更改。此规则的例外是查询会看到同一事务中较早语句所做的更改。此异常会导致以下异常:如果更新表中的某些行,则 SELECT 会看到更新行的最新版本,但它也可能会看到任何行的旧版本。如果其他会话同时更新同一个表,则异常意味着您可能会看到该表处于数据库中从未存在的状态。
重要的条件是,如果您更改行,您的一致读取将被“刷新”,因此它包括您刚刚所做的更改。
但是,如果您进行 UPDATE,则始终会更新该行的最新版本,而不是事务的一致性读取可以查看的版本。因此,如果另一个事务已经进行了该更改,则您的更新可能不会产生任何实际影响。这就是你观察到的情况。
因此,您的事务发出了更新,但没有更改该行。
这也许不是您希望 InnoDB 的行为方式,但它确实如此。
| 归档时间: |
|
| 查看次数: |
2714 次 |
| 最近记录: |