国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > SQL Server > 正文

SQL Server的隔離模式和鎖深入分析(一)

2024-08-31 00:48:11
字體:
來源:轉載
供稿:網友
最近在論壇上,看到很多sql server的鎖定模式和工作原理的討論。看來有必要總結一下。

      sql server有4中隔離模式,和多種鎖。我就簡單地整理一下心得體會,如有錯誤,敬請指正。

前言     

      隔離模式和鎖有差別,大家千萬不要搞混。隔離模式是規范了并發控制行為,而鎖是控制鎖定的粒度。但是兩者都會對你應用系統的并發法產生重大影響。缺省是read committed隔離模式和行級鎖(rowlock)。

      不同數據庫間,在這方面,有很多差別,也有共同的地方。這些表面現象其實在于體系架構上的差別。

      需要指出的一點是:我們不要去判斷這種差別孰優孰劣的問題,因為不同數據庫產品都有自己的指標。尤其用編程上的方便來判斷是很幼稚的。作為應用系統,應該是在編程開發上應該去適應數據庫,而不是讓數據庫來適應編程開發。因為數據庫的選型方案是更本不會考慮編程的方便與否。很多業務邏輯控制問題應該在系統設計上考慮,不能只依靠數據庫系統的鎖定機制來解決你應用系統的邏輯問題。

  read committed模式

       這是sql server缺省,也是大家最常用的一種。也是很多用過oracle人感覺不適應的地方。

      example:

      session 1  

      begin tran

      insert into t1 values(1,'allan')

      session 2

      select * from t1

      嗯?怎么回事,被掛住了。oracle中可不會,我看不到1,'allan'的這條記錄不就好了。

      其實這就是oracle和sql server在這一點上的差別。oracle采用了rollback的機制,保證了在read committed模式下行記錄鎖定不會影響其他事務的讀取(更新還是會被lock住的)。因此,oracle提供了更強的并發度。顯然,sql server簡化了這個架構,自然就只能這樣了。

      sql server在read committed模式下,一個事物的查詢語句是不會忽略其他事務未提交的數據(如果你的查詢條件包括了其他事務為提交的數據),sql server將讓你等待其他提交,從而保證數據一致性,顯然并發度比oracle低。如果出現了等待情況,大家可以根據這個標準來判斷。

      但是,兩個事務同時更新一條記錄或者插入主鍵相同的記錄的話,都會有一個等待,sql server和oracle都是這樣的。

      那么下面讓我用例子來仔細說明一下:

      測試表如下:
     
測試表如下:
c1 c2 c3
----------- --------------------- --------------------
1 200.5000 hellen
2 129.1400 hellen
3 288.9700 allan

session 1:

begin transaction

delete from test where c1=1



session 2:
select * from test
此時被掛住,因為包括了c1=1的記錄,sql server當然要求你等待。

如果我不選c1=1的記錄呢,自然就不會被waitting了。
session3:
select * from test where c1=2
select * from test where c1=3

c1 c2 c3
----------- --------------------- --------------------
2 129.1400 hellen

(所影響的行數為 1 行)

c1 c2 c3
----------- --------------------- --------------------
3 288.9700 allan

(所影響的行數為 1 行)



沒有被掛起,一切很好。


此時,還可以發現一個很有趣,很容易迷惑你的現象。
session 4
select * from test where c1<>1
結果也被掛住了,好像rowlock出了“問題”?不要急,原來由于我這個表test建了主鍵(c1字段)。我認為這是由于update,delete操作引起了索引上行的lock。
而此時,如果執行select * from test where c1>1是沒有問題的。

那么,我們只要強制跳過聚集索引的索引頁和索引葉節點頁(數據頁)中行鎖定的部分。
select * from test with(fastfirstrow) where c1<>1
果然就一切ok。
因此,對于很多現象,我們需要進一步地去思考和去解迷。


下面,我們通過sp_lock查看來在說明一下

通過sp_lock查看:
spid dbid objid indid type resource mode status
------ ------ ----------- ------ ---- ---------------- -------- ------ ------------------------------------
53 7 789577851 1 pag 1:126 ix grant
53 7 789577851 1 key (010086470766) x grant
53 7 789577851 1 pag 1:127 ix grant
53 7 789577851 2 key (090041892960) x grant
53 7 789577851 0 tab ix grant

(1)  id 789577851就是表test,可以查詢sysobjects。
(2) 關于tab的ix,是表結構的意向排他鎖 。此時,如果你執行alter table命令來改變表結構(會對表結構上x鎖)是會被掛住  的。
(3) pag是頁鎖,就是索引頁鎖,此時為什么會有兩個呢?顯然1:126是索引樹的中間頁節點頁面,而1:127是葉節點頁,也就是數據頁(聚集索引的表存儲結構)。因此,任何對索引頁上x鎖的操作都會被掛住,而上ix,s不會,sql server會進一步判斷行級鎖。此時,可以通過select * from test with(paglock) where c2=2測試。
(4) key (010086470766) ,key (090041892960) 的兩個x最明顯了,就是行級獨占鎖。一個是索引中間頁上的行級鎖,一個是葉節點(數據頁)上的行級鎖。

這就是sql server最常用的read committed隔離模式的情況,下次繼續討論read uncommitted隔離模式。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 九龙坡区| 黄石市| 怀宁县| 三明市| 绥中县| 彩票| 惠水县| 新建县| 庄浪县| 盖州市| 平舆县| 登封市| 南部县| 咸宁市| 老河口市| 开阳县| 洪江市| 石首市| 临猗县| 安龙县| 新泰市| 梅河口市| 清河县| 新昌县| 达孜县| 宜君县| 淳安县| 突泉县| 巴林右旗| 襄汾县| 兴国县| 丹凤县| 乌兰浩特市| 沧州市| 淳化县| 闸北区| 盖州市| 雷波县| 乌鲁木齐县| 定西市| 石楼县|