<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      SQL Server 中的事務和鎖(三)-Range S-U,X-X 以及死鎖

      在上一篇中忘記了一個細節。Range T-K 到底代表了什么?Range T-K Lock 代表了在 SERIALIZABLE 隔離級別中,為了保護范圍內的數據不被并發的事務影響而使用的一類鎖模式(避免幻讀)。它由兩個部分構成:

      第一個部分代表了他鎖定了一個索引范圍,在這個范圍內,所有索引使用 T 鎖進行鎖定;

      第二個部分是而這個范圍內已經命中的Key,這些 Key 將使用 K 鎖進行鎖定。

      合并在一起我們說在這個范圍內,索引范圍和特定的row的鎖定模式為 Range T-K。

      舉上一篇的一個例子吧:

      SELECT [data] FROM [MyTable] WHERE [index_column]>=20 AND [index_column]<=40

      的鎖的使用情況是:

      image

      實際上,上述語句產生的鎖有兩個部分,第一個是 Range S 鎖,范圍是 20-40 的索引范圍,第二是 Key 上使用的 S 鎖,在圖中可以看到有三個 Key 被命中了,分別是“無限遠”,“25”對應的索引以及“30”對應的索引。其 Mode 為 Range S-S,其 Type 為 KEY,也就是,他們的范圍鎖為 Range S,Key 鎖為 S 鎖。

      更新和插入操作涉及的鎖

      涉及的鎖主要是兩種,一種是 Range S-U 鎖,另一種是 Range X-X 鎖。

      Range S-U,這個選定索引范圍會獲得 S 鎖而命中的 Key 使用 U 鎖鎖定,以便將來轉換為 X 鎖。而在更新時,則徹底成為 X 鎖,這個范圍內的鎖模式也就成了 Range X-X。由于更新的數據列不同(有可能是索引列,有可能不是),使用的索引也不同(聚集,非聚集,唯一,等),因此其情況就不容易像 Range S-S 鎖那么容易得出規律了。總的來說有幾種情況還是一致的,這里就不再逐個實驗了(這里強烈推薦閱讀 SQL Server 2008 Internals 這本書關于鎖的章節,講述的很清楚):

      首先,在相等判斷(例如“=”),且索引為唯一索引的情況下。如果該索引命中,不會有 Range T-K 鎖鎖定記錄范圍,而相應的記錄直接獲得 U 鎖或者 X 鎖;

      其次,在相等判斷,不論索引是否為唯一索引,如果該索引沒有命中記錄,則 Range T-K 鎖鎖定 “下一個”記錄。(關于“下一個”的解釋請參見上一篇);

      第三,在范圍條件(>、<、BETWEEN),不論索引是否唯一,如果該索引命中,不但該范圍會獲得 Range T-K 鎖,而該范圍的“下一個”記錄也會獲得 Range T-K 鎖。

      為什么 Serializable 隔離級別更容易死鎖

      我們從第一篇的圖可以看到,SERIALIZABLE 級別能夠保證最嚴格的數據一致性,但是這些保衛的手段只要稍稍變化就可以發展為死鎖。事實上,在各種隔離級別中,數據一致性越高,則越容易發生死鎖;數據一致性越低,則發生死鎖的概率就越小。

      在這些隔離級別中,SERIALIZABLE 是最容易死鎖的,這得益于 Range T-K 鎖使鎖定的范圍不僅僅限于現有數據,還有未來數據;不僅僅限定現有的若干數據頁,而是一個廣大的范圍。

      這其中,最恐怖的問題莫過于“下一個”數據的鎖定。這非常容易造成大范圍死鎖。我們以第一篇的例子來說明:

      SELECT @findCount=COUNT(id) FROM MyTable
      WHERE [fk_related_id]=@Argument
      
      IF (@findCount > 0)
      BEGIN
      	ROLLBACK TRANSACTION
      	RETURN ERROR_CODE
      END
      
      INSERT INTO MyTable ([fk_related_id],…)
      VALUES (@Argument,…)
      
      COMMIT TRANSACTION
      RETURN SUCCESS_CODE

      在這個例子中,表 MyTable 的列 fk_related_id 是一個唯一索引(非聚集),事務隔離級別為 SERIALIZABLE。不同的存儲過程執行會傳入不同的 @Argument,表面看來,這不會有任何的問題,但是由于“下一個”數據的鎖定,在稍高水平的并發上,就出現了大約 80% 的失敗情況,這些失敗都來源于死鎖。我們挑選了其中的一次:

      我們試圖以每秒鐘 15 個的壓力在 @Argument 屬于 [1, 1000] 的范圍內進行存儲過程調用。在這個過程中,有一個 @Argument 為 115 的記錄首先成功的插入了進去!

      id fk_related_id data
      1 115

      接下來有一個 @Argument 為 74 的記錄獲得了機會,我們假設它的 Session Id 為 A。它執行了 SELECT 語句:

      id fk_related_id data
      1 115 (A 獲得了Range S-S Lock)

      接下來有一個 @Argument 為 4 的記錄獲得了機會,我們假設它的 Session Id 為 B。它執行了 SELECT 語句:

      id fk_related_id data
        115 (A 、B獲得了Range S-S Lock)

      接下來,Session A 執行到了 INSERT 語句,那么 Range S-S 鎖會試圖進行一個轉換測試(Range I-N 鎖),但這顯然是行不通的,因為 Session B 也獲得了 Range S-S Lock,因此 Session A 陷入了等待;

      而 Session B 也執行到了 INSERT 語句,相同的,它也陷入了等待;這樣,Session A 等待 Session B 放棄 Range 鎖,Session B 等待 Session A 放棄鎖,這是一個死鎖了。

      而更糟糕的事情是,凡是 @Argument 小于 115 的記錄,他都會試圖令下一個記錄獲得新的 Range S-S 鎖,從而進入無限的等待中,至少,1-115 號記錄死鎖,并且最終 114 個需要放棄,1個成功。這就是為什么 SERIALIZABLE 隔離級別不但會發生死鎖,而且在某些時候,是大面積死鎖。

      總之:在 SERIALIZABLE 隔離級別下,只要有類似同一索引為條件先讀后寫的狀況的,在較大并發下發生死鎖的概率很高,而且如果碰巧既有的記錄索引按照排序規則在非常靠后的位置,則很可能發生大面積死鎖。

      那么如何解決這個問題呢,呃,降低隔離級別當然是一個方法,例如,如果你能接受幻讀,那么 REPEATABLE READ 是一個不錯的選擇。但是我突然在某篇博客中看到了使用 SELECT WITH UPDLOCK 的方法。事實上,這種東西讓死鎖更容易了。

      例如,一個存儲過程 SELECT B,而后 SELECT A;而另外的存儲過程先 SELECT A,再 SELECT B,那么由于順序不同,排他鎖僅僅是 Read 的情況就可能發生死鎖了。

      那么為什么 REPEATABLE READ 會好得多呢?因為 REPEATABLE READ 緊緊鎖定現有記錄,而不會使用 Range 鎖。我們仍然以上述存儲過程為例,這樣,只有兩個被鎖定的行數據在同一個頁上(因為默認情況下使用頁級鎖),或者說挨得足夠近,才有可能死鎖,并且這個死鎖僅僅限于這個數據頁上的記錄而不會影響其他記錄,因此死鎖的概率大大降低了。

      我們實際測試中,在相同的測試條件下,并發提高到 100 的情況下時才有不到 0.1% 的死鎖失敗幾率。當然我們付出了允許幻讀的代價。

      posted @ 2011-10-25 23:23  TW-劉夏  閱讀(4344)  評論(1)    收藏  舉報
      主站蜘蛛池模板: 国内不卡的一区二区三区| 久久国产自偷自偷免费一区 | 日韩有码中文字幕av| 四虎精品免费永久免费视频| 99在线视频免费观看| 日本精品网| 国产强奷在线播放免费| 国产成人一区二区三区免费| 加勒比无码人妻东京热| 少妇又爽又刺激视频| 国产精品国产自产拍高清| 免费看又黄又无码的网站| 国产福利酱国产一区二区| 国产精品免费观看色悠悠| 精品综合久久久久久97| 看全色黄大黄大色免费久久| 亚洲婷婷综合色高清在线| 无码人妻久久一区二区三区app| 中文激情一区二区三区四区| 无码午夜福利片| 国产精品午夜福利免费看| 国产三级精品福利久久| 大胸美女被吃奶爽死视频| 浪潮av色综合久久天堂| 最新国产精品好看的精品| 熟妇好大好深好满好爽| 久久国产精品色av免费看| 国产精品中文字幕自拍| 热re99久久精品国产99热| 国产一区二区三区无遮挡| A毛片终身免费观看网站| 射阳县| 国产精品无码专区av在线播放 | 亚洲成人av综合一区| 欧美高清狂热视频60一70| 国产av熟女一区二区三区| 无码伊人久久大杳蕉中文无码| 中文字幕人妻丝袜美腿乱| 大陆精大陆国产国语精品| 真人抽搐一进一出视频| 久久妇女高潮喷水多|