第十六章

Transactions管理:鎖與隔離數據

•為什麼需要隔離

•在多用戶環境中,交易數據同時訪問

•並不是獨立的數據將會不精確

•自動隔離,以防止相互矛盾修改數據機制

•間隔鎖

•鎖的間隔決定多少數據被孤立

•在Adaptive Server中有三種間隔

–Table-level lock

–Page-level lock

–Row-level lock

•鎖的類型

•鎖的類型的數據被隔離程度決定來自其他transactions

•三種類型的鎖

–Shared (共享鎖)

•用於讀取數據的陳述(selects)

•其他進程可以讀取數據(數據共享鎖),但沒有進程可以改變數據(數據獨占鎖)

–Exclusive (獨占鎖)

•用於陳述,變更數據(inserts,updates,deletes)

•沒有其他進程可以讀取數據(數據共享鎖)或改變數據(頁面上的獨占鎖)

–Update (更新鎖)

•用於操作可能會或可能不會改變的數據(updates,deletes)

•當進程第一次掃描的數據,它適用於一個更新鎖。其他進程可以放置共享鎖,但沒有進程的數據上放置獨占鎖或更新鎖

•對每個類型的鎖定間隔

•鎖的類型摘要

*Updates和Deletes使用獨占鎖,只有當他們找到需要修改的數據

•鎖的系統程序

•sp_intent

•intent 的意義:在table的最外層,告知其他要對table做動作的人員,目前table內有人做lock的動作

•顯示目前持有的鎖的信息

–locktype的列列出了每個鎖的間隔和類型

–Sh – Shared lock

–Ex – Dxclusive lock

–Update – Update lock

•死鎖

•死鎖發生時,有兩個或兩個以上的transactions數據鎖,每一筆transactions正在等待其他transactions已鎖定的數據獲取鎖

•解決死鎖

•Adaptive Server會自動檢測死鎖,並選擇已累計transaction量最少的CPU時間,是受害者。受害人被中止和transaction的用戶@ @1205錯誤值將返回錯誤消息

•預防死鎖

•為了盡量減少死鎖的可能性

•繁忙爭奪的表鎖定方案修改只有一個數據鎖定方案

•所有transactions在同一個命令下的訪問資料表

•使transactions盡可能小

•盡快提交transactions

•避免使用holdlock選項,除非需要重複讀取

•避免在transaction中要求用戶輸入

•盡量減少死鎖造成的錯誤

•應用程序檢查錯誤1205訊息

•然後重新提交已為受害人選擇的過程

•鎖定方案

•一個鎖定方案是根據一個表的屬性決定其中與該表相關聯的數據被鎖定

•Adaptive Server有三個鎖定方案

–Allpages locking (APL)

•可以鎖定索引頁

•服務器使用表鎖和頁面鎖,但不能使用列鎖

–Datapages locking (DPL)

•從不鎖定索引頁

•服務器使用表鎖和頁面鎖,但不能使用列鎖

–Datarows locking (DRL)

•從不鎖定索引頁

•服務器使用表鎖和行鎖

•鎖定方案比較

•設置鎖定方案

create table table_name(

column_name datatype [ NULL | NOT NULL | IDENTITY ],

...

column_name datatype [ NULL | NOT NULL | IDENTITY ] )

[ lock { allpages | datapages | datarows } ]

如果沒有特別設定鎖定方案,系統會使用預設的鎖定方案

•鎖定方案系統程序

•sp_configure "lock scheme"

•顯示預設的鎖定方案

•sp_configure "lock scheme", 0, { allpages | datapages | datarows }

•更改預設的鎖定方案

•更改預設的鎖定方案需要具有sa_role

•閱讀是非隔離數據

•有三種類型的查詢,或“讀”,可以返回數據但不準確因為數據被隔離

•會讀取這些類型關係數據庫管理系統的每個層面

•讀取的三種類型

•Dirty reads

•Transaction 1 修改數據

•Transaction 2 讀取數據在修改之前

•這個Transactions的讀取行為就稱為「未認可」或「Dirty(骯髒)」的數據

•Nonrepeatable reads

•Transaction 1 讀取數據

•Transaction 2 修改數據在第一個Transaction完成之前

•第一次讀取的行為是「Nonrepeatable(不可重複)」

•Phantom reads

•Transaction 1 讀取符合條件一組行的數據

•Transactions 2 修改數據,使部分列的數據不相符合現在做的條件,和/或部分列的數據符合的條件不再做

•出現和消失的行被稱為「Phantom(幻影)」

•隔離級別

•隔離級別是一組允許或阻止特定組合的三種類型讀取鎖的行為

•ANSI定義隔離四個層次,每一個比之前更嚴格

•Level 0

•持有共享鎖直到select完成讀取該行或頁

•select忽略獨占鎖

•這是不同於Level 1 的行為

•Level 1

•持有共享鎖,直到select結束行或頁的閱讀

•select等待獨占鎖被釋放

•Level 2

•持有共享鎖,直到transaction結束

•這不同於Level 1 的行為

•select等待獨占鎖被釋放

•Level 2獨立行為要求行級鎖

•APL表和DPL表沒有行級鎖

•如果在查詢隔離Level 2時讀取APL表或DPL表,是隔離Level 3 的行為代替執行

•Level 3

•持有共享鎖,直到transaction結束

•這不同於Level 1 的行為

•select等待獨占鎖被釋放

•設置隔離級別

•語法session級別隔離

set transaction isolation level {

0 | read uncommitted |

1 | read committed |

2 | repeatable read |

3 | serializable }

•語法statement級別隔離

select ...

at isolation {

0 | read uncommitted |

1 | read committed |

2 | repeatable read |

3 | serializable }

•@@isolation返回隔離等級session

•2和3等級基本上是一樣的

•holdlock and noholdlock

•holdlock:強制隔離Level 3 的行為,不管當前的隔離等級

•這個select共享鎖直到transaction結束時持有

•noholdlock:強制隔離Level 1 的行為,不管當前的隔離等級

•當行或頁已讀該select共享鎖被釋放

•select column_list from table_list [ holdlock | noholdlock ]

•holdlock等於Level 2、3