Bes*_*ces 5 mysql postgresql oracle locking
根据隔离级别,可能会展示 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... set version=6 ... WHERE primary_key = 1234 AND version = 5
Thread B: UPDATE... set version=6 ... WHERE primary_key = 1234 AND version = 5
Run Code Online (Sandbox Code Playgroud)
如果线程 A 和线程 B 同时进入他们的事务,并且线程 B 在线程 A 之后执行更新,线程 B 的更新是否会更新任何行或它是否会“看到”版本 5 的记录并因此覆盖线程写了?
它依赖于数据库吗?例如Oracle vs MySql vs PostgreSQL?
在 MS SQL Server 中,我可以说这取决于您的隔离级别。如果您通过使其“快照隔离”将其设置为与 Oracle 更相似,则线程 A 尝试更新的最后一行将“之前”值复制到tempdb
,并且所有读取都将在通过行更新时读取该值锁。
如果您具有已提交读的默认隔离级别,它将锁定该行(或在某些情况下为页面),从而在更新时阻止您的读取器访问该特定行或页面。除非您在查询子句上指定SET ISOLATION LEVEL READ UNCOMMITTED
或添加提示,从而允许脏读。(NoLock)
FROM
这一切都与 ACID 中的隔离级别有关,并且它是您在 MS SQL Server 中可以控制的唯一 ACID 属性。