Bes*_*ces 3 mysql database oracle postgresql
隔离级别仅适用于SELECTS而不是更新吗?
为SELECTS展示不同隔离行为的场景
1) 0:00 Thread A runs a query that returns 1000 rows that takes 5 minutes to complete
2) 0:02 Thread B runs a query that returns the same 1000 rows
3) 0:05 Thread A updates the last 1 rows in this result set and commits them
4) 0:07 Thread B's query returns*
Run Code Online (Sandbox Code Playgroud)
根据隔离级别,#4中的结果集将包含线程A的更改,或者不包含.UPDATES也是如此吗?
以下是一个示例场景:
Thread A: UPDATE ... WHERE primary_key = 1234 AND version = 5
Thread B: UPDATE ... WHERE primary_key = 1234 AND version = 5
Run Code Online (Sandbox Code Playgroud)
如果线程A和线程B同时进入它们的事务,并且线程B在线程A之后执行其更新,则线程B的更新将失败还是它将"看到"具有版本5的记录并因此成功?
它取决于数据库吗?例如Oracle vs MySql vs PostgreSQL?
假设您打算显示许多ORM使用的"乐观锁定"模式,例如:
Thread A: UPDATE ... SET ..., version = 6 WHERE primary_key = 1234 AND version = 5
Thread B: UPDATE ... SET ..., version = 6 primary_key = 1234 AND version = 5
Run Code Online (Sandbox Code Playgroud)
然后在所有合理的隔离级别(我不是100%确定READ UNCOMMITTED - 大多数DB甚至不支持它)线程B将匹配没有行并且没有效果.
例如,在PostgreSQL中,线程B最初将匹配与A相同的行,但在行更新锁定时阻塞,直到线程A提交或回滚.此时它将重新检查条件并发现如果线程A已提交则不再匹配,因此它将不执行任何操作.行锁定意味着序列化冲突在这种特定情况下永远不会起作用.
在任何合理的数据库中,只有两个更新中的一个会成功 - 第二个将匹配零行或中止序列化失败,具体取决于隔离级别和数据库实现.即使在带有InnoDB的MySQL中也是如此(请参阅本答复中的详细说明和演示)至少在5.5中.如果你正在使用MyISAM,那么正确性和可靠性显然不是你的大问题;-)
我不知道有任何数据库对UPDATEs vs SELECTs 应用不同的隔离规则.毕竟,它UPDATE需要为其WHERE子句,子查询等提供相同的隔离保证SELECT.UPDATEs可以死锁哪个SELECT不能(在PostgreSQL中;显然它们可以在MySQL + InnoDB中).与s 不同SELECT,UPDATEs在SERIALIZABLE隔离模式下会出现序列化失败- 但它们具有相同的可见性规则.
PostgreSQL关于并发控制的文档很好地解释了这一点.
| 归档时间: |
|
| 查看次数: |
240 次 |
| 最近记录: |