文章出處

RDBMS能在事務中維護數據的完整性,這是通過數據庫對象實現的多種機制來實現的,下面列出的是4個最重要的對象:

  • 約束
  • 索引

      在SQL Server中,鎖可以使多個用戶同時訪問,同一數據,并且保證在讀取數據時,數據不會被修改。同時,鎖也用來確保一個進程在修改數據時,不和其他進行數據修改操作或者數據讀取操作的進程發生沖突。

      SQL Server以連接為單位對鎖進行管理,這就是說,一個鎖不能被多個連接同時持有;SQL Server也以事務為單位對鎖進行管理,和多個連接不能同時持有同一個鎖一樣,多個事務也不能同時持有,同一個鎖。

       比如,假如一個應用程序打開了一個SQL Server連接,這個連接在某個表上,被賦予了共享鎖,這個應用程序就不能再打開一個可以修改該表數據的新連接。對事物也是一樣。如果一個應用程序啟動了一個用于修改特定數據的事務,那么在這個事務的工作完成之前,其他任何事物,都不能修改這些數據。即使多個事務共享相同的連接,上述情況也成立。

      SQL Server使用6種類型的鎖,更準確的說,是6種資源鎖模式:

  • 共享
  • 更新
  • 排他
  • 意向
  • 模式
  • 批量更新

共享鎖,更新鎖,排他鎖和意向鎖可用于表或索引的行、頁(表,或者索引所用的8KB的存儲頁面)、擴展(64KB的8個連續的索引或者表頁面)、表,數據庫。

模式鎖與批量更新鎖適用于表。

       共享鎖

       共享鎖允許多個連接和事務同時讀取所分配的共同資源。只要給連接和事務授予了共享鎖,任何其他連接或事務就不能修改數據。當一個應用程序成功的讀取了數據之后,共享鎖通常會被釋放,但在某些特殊情況下,這個動作是可以修改的。例如:給整個事務分配了共享鎖,保證事務基于的數據,在該事務完成之前不被修改,從而最大限度的確保數據的一致性。這個擴展鎖,可用于事務一致性必須100%保證的情況,但持有鎖的代價是降低了數據的并發訪問,例如,要從儲蓄賬戶中取100美元,在包含儲蓄賬戶的余額上放置一個共享鎖。這些數據用于確保有足夠的資金支持這個取款操作。最好禁止其他連接修改該余額,直到取款操作完成為止。 由于共享鎖之間是互相兼容的,因此,不同的事務和連接在讀取相同的數據時,不會發生沖突。

      更新鎖

      SQL Server使用更新鎖,在防止出現死鎖的情況。出現死鎖是很糟糕的,通常死鎖是由于拙劣的編程技術造成的。當兩個進程爭奪同一個資源時,就將發生死鎖。回到前面銀行的例子:在這個假定的銀行事務中,我妻子和我同時上線,將儲蓄賬戶中的資金轉帳到支票賬戶上。碰巧我們同時要進行轉賬,于是兩個進程分別啟動并執行了轉賬操作。當我的進程訪問這兩個賬戶時,進程在資源上發出了共享鎖。到目前為止一切還算正常,但是當我們的進程試圖修改資源時,混淆便隨之而來了。首先,我妻子的進程嘗試將共享鎖升格為排他鎖,以便對數據進行修改。幾乎同時,我的進程也嘗試進行相同的升格操作。然而,我們所共有的共享鎖阻止了任何一個進程,實現升格到排他鎖的企圖。由于沒有一個進程愿意釋放其,共享鎖,就發生了死鎖。

      SQL Server不會對死鎖現象特別關照,假如死鎖發生了,SQL Server就會自動選擇其中的一個進程,將它作為犧牲品而停止。SQL Server選擇與其關聯代價最小的進程,停止它,回滾相關事務,然后向相關應用程序中返回錯誤代碼1205.如果用戶正確的捕捉到了錯誤,就會得到這樣的消息:“事務##在X資源上與其他進程,出現了死鎖,并被選擇為死鎖的犧牲品,重新運行事務”。

      為了防止死鎖發生,SQL Server通常使用更新鎖來代替共享鎖。只有一個進程可以得到更新鎖,這樣可以防止與其相對的進程升格其擁有的鎖,其底線是,如果以更新為唯一目的而進行了讀操作,則SQL Server可以發出一個更新鎖,而不是共享鎖,以便避免潛在的死鎖危險。SQL提供了防止死鎖的邏輯,只要細心的規劃與實現,就可以避免死鎖的產生。

      排他鎖

      在執行修改操作時,SQL Server通常發出排他鎖。在更改一行匯總的某個字段值的時候,SQL Server授予相關進程訪問此行的排他訪問權限。這樣的排他訪問,可以防止任何并發事務或者連接的相關進程,對處于修改中的數據,進行讀、更新、刪除操作。排他鎖與任何其他類型的鎖都不兼容。

      意向鎖

      為了防止任何一個并發事務,或者連接中的進程,在一個已經被其他進程鎖住的資源上,放置排他鎖,SQL Server設計了意向鎖。比如,執行一個事務,在表中更新單個行,SQL Server在該行上授予此事務排他鎖的同時,也在包含此行的表上授予此事務意向鎖。這樣就能防止其他進程在該表中放置排他鎖。    

     舉一個現實中的例子:它可以解釋SQL 編程中意向鎖的行為:用戶住進了SQL旅館的404房間,現在具有使用4樓的房間4的唯一(排他)權限。旅館的其他主顧都不允許進入此房間。而且沒有主顧可以將旅館的所有房間都預定下來,因為404房間已經被用戶單獨占用。對于旅館,用戶就有了意向鎖;而對于404房間,用戶有排他鎖。意向鎖,與其他比它低級的鎖,都是兼容的。

     批處理更新鎖

     表上的批處理更新鎖允許多個批處理加載線程,把數據加載到表中,同時禁止其他類型的數據訪問。在表上啟用表鎖定時,或者用批處理操作選擇表鎖定選項時,就發出了批處理更新鎖。 

     鍵范圍鎖

     在使用可串行化的隔離級別時,鍵范圍鎖保護結果集中隱含的一個行范圍,不被T-SQL語句讀取。可串行化的隔離級別要求,在事務中每次查詢時,都必須獲得相同的行集。鍵范圍鎖,禁止其他事務插入其鍵值(由可串行化的事務讀取)在指定的范圍內的新行,來滿足這個要求。

    

 

 


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()