大多數RDBMS允許獲取所選行上的共享排他鎖。例如,PostgreSQL有這樣的語法:爲什麼無法通過顯式鎖定查詢語法獲取謂詞鎖
SELECT *
FROM post
WHERE id=10
FOR SHARE;
使用FOR SHARE,我們甚至可以在READ_COMMITTED隔離級別獲取共享鎖,並且可以在不實際使用REPEATABLE_READ事務隔離來防止非重複讀現象。
但是爲了防止幻像讀取,SERIALIZABLE是唯一的方法。爲什麼沒有明確的鎖定語法來獲取謂詞鎖定呢?
據我所知,我不記得在Oracle,SQL Server,MySQL或PostgreSQL中看到任何這樣的構造。
因爲我記得FOR SHARE與SELECT FOR UPDATE具有相同的語義。您將收到READ LOCK以讀取涉及選擇的所有表格。 另一方面,SERIALIZABLE lvl也爲您提供了WRITE LOCK。另外,SELECT FOR UPDATE在Oracle中具有相同的語義,例如 – ivanenok
FOR SHARE獲取讀鎖,而FOR UPDATE則爲您提供寫鎖。當使用SERIALIZABLE時,數據庫同時獲取所有檢索到的行上的共享鎖(以防止模糊讀取)以及範圍/謂詞鎖(以防止幻像讀取)。 –
爲什麼要在每個查詢中強制執行事務隔離級別,而不僅僅是使用事務隔離級別?在Oracle中,您總是可以對SCN使用閃回查詢以避免幻讀(如果將事務隔離級別設置爲可串行化,這就是Oracle正在做的事情)。這不需要任何形式的鎖定或任何其他會話阻塞。但它不會具有拋出ORA-08177的相同行爲:無法對不可序列化的修改序列化針對此事務錯誤的訪問。 –