[SQL Server] 鎖定使用的藝術 (Part 1) - 鎖定控制類型

只要是寫到資料庫存取程式,而且程式又是多人運作 (這裡的多人是指 100 個人以上同時存取) 的環境時,很難不碰到並行處理 (Concurrency Process) 的問題,並行處理在資料庫系統中是一門很重要的學問,因為它一定會出現在商業運轉的環境,而且問題不只是資料庫,像是執行緒的處理也會遇到這樣的問題,所以在並行環境下資料庫都會有一些行動或處理方式,鎖定 (Lock) 就是其中一種。

註:本文僅說明在 ADO 中的 LockType,不說明細部的設定。

只要是寫到資料庫存取程式,而且程式又是多人運作 (這裡的多人是指 100 個人以上同時存取) 的環境時,很難不碰到並行處理 (Concurrency Process) 的問題,並行處理在資料庫系統中是一門很重要的學問,因為它一定會出現在商業運轉的環境,而且問題不只是資料庫,像是執行緒的處理也會遇到這樣的問題,所以在並行環境下資料庫都會有一些行動或處理方式,鎖定 (Lock) 就是其中一種。

並行這個名詞出現在作業系統 (Operating Systems),代表許多執行緒或行程會存取同一個資源,而作業系統必須要採取某些行動,才可以讓所有程式都存取的到,又不會發生打結的現象。而在資料庫中,並行所要存取的資源是資料列或資料欄,因此資料庫會採用鎖定的方法來阻止多個要求搶奪存取權,而鎖定方式基本上會有兩種:列層次鎖定 (row-level locking) 與欄層次鎖定 (column-level locking) 或是支援更多的鎖定機制,在 SQL Server 中,支援了 11 種不同物件的鎖定機制,資料庫引擎會自己判斷資源的存取狀況決定要使用何種鎖定機制。

而資料庫引擎在決定使用何種鎖定策略前,會先決定鎖定的控制類型,先由用戶端程式所要求的控制類型來處理,若用戶端程式沒有要求時才會由資料庫的預設值來處理,而鎖定的控制類型有兩種:

  • 悲觀鎖定 (Pessimistic Locking),表示資料庫引擎認為更新資料的動作不會順利,因此會將資料的鎖定時間拉長到鎖定被釋放為止,這會保證更新一定會寫入,但缺點就是會拉長鎖定時間。
  • 樂觀鎖定 (Optimistic Locking),表示資料庫引擎認為更新資料的動作一定會順利,因此不會對讀取的動作進行鎖定,讓讀取的速度可以加快,但如果在讀取時有別的使用者修改了資料以致於讀取不同步時,就會出現 Optimistic Locking Exception,也就是 DbConcurrencyException 例外狀況。

ADO 中支援了五種鎖定控制類型,分別是:

  • adLockBatchOptimistic (=4),指示在批次處理時使用樂觀鎖定。
  • adLockOptimistic (=3),指示以樂觀鎖定方式處理。
  • adLockPessimistic (=2),指示以悲觀鎖定方式處理。
  • adLockReadOnly (=1),指示將資料集設為唯讀。
  • adLockUnspecified (=-1),不明確設定鎖定類型。

在實務上,如果使用伺服器游標 (server cursor) 的話,那麼使用樂觀鎖定是可以保證讓速度較快的作法,而且藉由 server cursor,可以由伺服器來處理並行問題,用戶端的程式可以寫的乾淨些,但如果對資料的正確度很要求的話,則要使用悲觀鎖定以保證資料一定會寫入資料庫,當然,如果信任伺服器的並行處理能力的話,也可以只使用樂觀鎖定。

 

To be continued…

Reference:

SQL Server Documentation, Concurrency Control Type.