1. 程式人生 > >1.2 併發控制

1.2 併發控制

無論何時,只要有多個查詢需要在同一時刻修改資料,就會產生併發控制的問題。

MySQL提供鎖來防止資料損壞,但是這種方案並不支援併發處理。

1.2.1 讀寫鎖

   共享鎖(Shared),簡寫為 S 鎖,又稱讀鎖。是共享的,或者說是相互不阻塞的。多個客戶在同一時刻可以同時讀取同一個資源,而互不干擾。

     排它鎖(Exclusive),簡寫為 X 鎖,又稱寫鎖。是排他的,也就是說一個寫鎖會阻塞其他的寫鎖和讀鎖,這是出於安全策略的考慮,只有這樣,才能確保在給定的時間裡,只有一個使用者能執行寫入,並防止其他使用者讀取正在寫入的同一資源。    

  有以下兩個規定:

  • 一個事務對資料物件 A 加了 X 鎖,就可以對 A 進行讀取和更新。加鎖期間其它事務不能對 A 加任何鎖。
  • 一個事務對資料物件 A 加了 S 鎖,可以對 A 進行讀取操作,但是不能進行更新操作。加鎖期間其它事務能對 A 加 S 鎖,但是不能加 X 鎖。

1.2.2 鎖粒度

  MySQL 中提供了兩種封鎖粒度:行級鎖以及表級鎖。

  應該儘量只鎖定需要修改的那部分資料,而不是所有的資源。鎖定的資料量越少,發生鎖爭用的可能就越小,系統的併發程度就越高。

  但是加鎖需要消耗資源,鎖的各種操作(包括獲取鎖、釋放鎖、以及檢查鎖狀態)都會增加系統開銷。因此封鎖粒度越小,系統開銷就越大。

  在選擇封鎖粒度時,需要在鎖開銷和併發程度之間做一個權衡。

  1. 表鎖(table lock)是MySQL中最基本的鎖策略,並且是開銷最小的策略。它會鎖定整張表。一個使用者在對錶進行寫操作(插入、刪除、更新等)前,需要先獲得寫鎖,這會阻塞其他使用者對該表的所有讀寫操作。只有沒有寫鎖時,其他讀取的使用者才能獲得讀鎖,讀鎖之間是不相互阻塞的。

  2. 行級鎖(row lock)可以最大程度地支援併發處理(同時也帶來了最大的鎖開銷)。在InnoDB和XtraDB,以及其他一些儲存引擎中實現了行級鎖。行級鎖只在儲存引擎層實現,而MySQL伺服器層沒有實現。伺服器層完全不瞭解儲存引擎中的鎖實現。