Azure-Sql-Database

無法在 Azure SQL 上將 READ_COMMITTED_SNAPSHOT 設置為 OFF

  • February 2, 2022

我和我的團隊正在嘗試將 Azure SQL 用於我們的開發環境,但在我們的生產環境的鎖定行為中遇到了一些關鍵且不需要的差異。主要問題是增量值重複,因為將 READ_COMMITTED_SNAPSHOT 設置為 ON,xlock、holdlock、rowlock 不會阻止對其他事務的選擇,所以我們得到了典型的:

  • $$ tran1 $$選擇值 (1),
  • $$ tran2 $$選擇值 (1),
  • $$ tran1 $$更新值(++1),
  • $$ tran2 $$更新值 (++1)

而不是第二個事務將值設置為 3。

我們將其追踪到在 Azure SQL 中將 READ_COMMITTED_SNAPSHOT 設置為 ON,這是預設設置,這與您自己設置 SQL Server 不同(這很奇怪,但不要詳述)。

太好了,所以現在我們只需要將 READ_COMMITTED_SNAPSHOT 設置為 OFF,但這就是我們卡住的地方。在 Azure SQL 中,我們似乎無法做到這一點,即使沒有其他程序連接到伺服器,我們總是會遇到死鎖:

ODBC 錯誤:狀態:40001:錯誤:1205 消息:'

$$ Microsoft $$$$ ODBC Driver 17 for SQL Server $$$$ SQL Server $$事務(程序 ID 120)與另一個程序在鎖資源上死鎖,並已被選為死鎖犧牲品。重新執行事務。’。 即使我們使用立即回滾執行更改:ALTER DATABASE

$$ xxx $$SET READ_COMMITTED_SNAPSHOT OFF WITH ROLLBACK IMMEDIATE 我們花了一些時間試圖解決這個問題,但到目前為止沒有成功,求助!

Azure SQL 數據庫的預設數據庫範圍設置是通過將 READ_COMMITTED_SNAPSHOT 和 ALLOW_SNAPSHOT_ISOLATION 數據庫選項都設置為 ON 來啟用已送出的讀取快照隔離 (RCSI)。您不能更改數據庫預設隔離級別。但是,您可以在連接上顯式控制隔離級別。一種方法是,在開始事務之前,可以在 Azure SQL 數據庫中使用以下任一語句:

SET TRANSACTION  ISOLATION LEVEL  SERIALIZABLE
SET TRANSACTION  ISOLATION LEVEL  SNAPSHOT
SET TRANSACTION  ISOLATION LEVEL  REPEATABLE READ
SET TRANSACTION  ISOLATION LEVEL  READ COMMITTED
SET TRANSACTION  ISOLATION LEVEL  READ UNCOMMITTED

SET TRANSACTON ISOLATION LEVEL 控制由連接到 SQL Server 並跨批處理(GO 語句)發出的 Transact-SQL 語句的鎖定和行版本控制行為。以上所有的工作方式與 SQL Server 完全相同。

另外,上面的語句“SET TRANSACTION ISOLATION LEVEL READ COMMITTED”會將隔離級別設置為讀送出快照隔離(RCSI)。此隔離級別不同於已送出讀 (RC)。換句話說,“SET TRANSACTION ISOLATION LEVEL READ COMMITTED”在本地 SQL Server 中的預設行為是 RC,但在 Azure SQL 數據庫中是 RCSI。如果你想在 Azure SQL 數據庫中使用精確的 RC(不是 RCSI)行為,您必須為 SQL 語句設置鎖定提示。

READCOMMITTEDLOCK是提示。

通過使用鎖定指定讀取操作符合 READ COMMITTED 隔離級別的規則。數據庫引擎在讀取數據時獲取共享鎖,並在讀取操作完成時釋放這些鎖,而不管 READ_COMMITTED_SNAPSHOT 數據庫選項的設置如何

現在在 Azure 中進行自己的 SQL Server 設置可能不會那麼奇怪。您可以獲得預裝了不同版本 SQL Server 的 Azure VM,無需進行任何 SQL 設置。然後您可以安裝 SSMS 並使用它將數據庫選項“Is Read Committed Snapshot On”設置為 OFF。這會有幫助嗎?

引用自:https://dba.stackexchange.com/questions/244766