SQLServer中的事務加鎖策略

2021-09-08 05:31:10 字數 3194 閱讀 1173

乙個事務的例子:

tim要給bill轉賬100塊錢:

1.檢查tim的賬戶餘額是否大於100塊;

2.tim的賬戶減少100塊;

3.bill的賬戶增加100塊;

這三個操作就是乙個事務,必須打包執行,要麼全部成功,要麼全部不執行,其中任何乙個操作的失敗都會導致所有三個操作「不執行」——回滾。

原子性:

乙個事務必須保證其中的操作要麼全部執行,要麼全部回滾,不可能存在只執行了一部分這種情況出現。

一致性:

資料必須保證從一種一致性的狀態轉換為另一種一致性狀態 。

比如上乙個事務中執行了第二步時系統崩潰了,資料也不會出現bill的賬戶少了100塊,但是tim的賬戶沒變的情況。要麼維持原裝(全部回滾),要麼bill少了100塊同時tim多了100塊,只有這兩種一致性狀態的。

隔離性:

在乙個事務未執行完畢時,通常會保證其他session 無法看到這個事務的執行結果。

永續性:

事務一旦commit,則資料就會儲存下來,即使提交完之後系統崩潰,資料也不會丟失。

在多使用者都用事務同時訪問同乙個資料資源的情況下,有可能造成以下幾種資料錯誤:

不可重複讀:

如果乙個使用者在乙個事務中多次讀取一條資料,而另外乙個使用者則同時更新啦這條資料,造成第乙個使用者多次讀取資料不一致。

髒讀:第乙個事務讀取第二個事務正在更新的資料表,如果第二個事務還沒有更新完成,那麼第乙個事務讀取的資料將是一半為更新過的,一半還沒更新過的資料,這樣的資料毫無意義。

幻讀:第乙個事務讀取乙個結果集後,第二個事務,對這個結果集經行增刪操作,然而第乙個事務中再次對這個結果集進行查詢時,資料發現丟失或新增。

然而資料庫鎖,就是為解決這些問題所生的,他的存在使得乙個事務對他自己的資料塊進行操作的時候,而另外乙個事務則不能插足這些資料塊。這就是所謂的資料庫。

大致可以分為6種:

共享鎖(s):還可以叫他讀鎖。可以併發讀取資料,但不能修改資料。也就是說當資料資源上存在共享鎖的時候,所有的事務都不能對這個資源進行修改,直到資料讀取完成,共享鎖釋放。

排它鎖(x):還可以叫他獨佔鎖、寫鎖。就是如果你對資料資源進行增刪改操作時,不允許其它任何事務操作這塊資源,直到排它鎖被釋放,防止同時對同一資源進行多重操作。

更新鎖(u):防止出現死鎖的鎖模式,兩個事務對乙個資料資源進行先讀取在修改的情況下,使用共享鎖和排它鎖有時會出現死鎖現象,而使用更新鎖則可以避免死鎖的出現。資源的更新鎖一次只能分配給乙個事務,如果需要對資源進行修改,更新鎖會變成排他鎖,否則變為共享鎖。

意向鎖:sql server需要在層次結構中的底層資源上(如行,列)獲取共享鎖,排它鎖,更新鎖。例如表級放置了意向共享鎖,就表示事務要對錶的頁或行上使用共享鎖。在表的某一行上上放置意向鎖,可以防止其它事務獲取其它不相容的的鎖。意向鎖可以提高效能,因為資料引擎不需要檢測資源的每一列每一行,就能判斷是否可以獲取到該資源的相容鎖。意向鎖包括三種型別:意向共享鎖(is),意向排他鎖(ix),意向排他共享鎖(six)。

架構鎖:防止修改表結構時,併發訪問的鎖。

大容量更新鎖:允許多個執行緒將大容量資料併發的插入到同乙個表中,在載入的同時,不允許其它程序訪問該錶。

鎖相容性具體參見:

鎖粒度和層次結構參見:

例1:先開啟第一視窗,然後再開啟第二個視窗執行下面的語句

--第乙個視窗

begin tran

waitfor delay '0:0:10' --等待10秒執行下面的語句

select * from table

commit tran

--第二個視窗

select * from table

可以看到第二個視窗會立即查詢得到結果,這說明資料庫在對第乙個視窗進行查詢的時候加入了共享鎖,可以同時讀取資料。

例2:先開啟第一視窗,然後再開啟第二個視窗執行下面的語句

--第乙個視窗

begin tran

update user set name = 'tony' where id=1

waitfor delay '0:0:10' --等待10秒執行下面的語句

commit tran

--第二個視窗

select * from table

這時第二個視窗需要等待第乙個視窗的語句執行完才進行查詢,這說明資料庫對第乙個視窗進行查詢的時候加入了排他鎖,在處理語句之前,資料庫會對語句進行判斷需要加上那種型別的鎖。

例3:死鎖的處理策略,這是兩個延遲處理的兩個事務,都在等對方釋放資源,會導致死鎖

--第乙個視窗

begin tran

update user set name='tony' where age=6

waitfor delay '0:0:10' --等待10秒執行下面的語句

update information set remake = 'str' where name ='aaa'

commit tran

--第二個視窗

begin tran

update information set remake ='str' where name='gai'

waitfor delay '0:0:10' --等待10秒執行下面的語句

update user set name = 'tony' where age=5

commit tran

此時視窗一的執行結:

視窗2的執行結果:

可以看出,視窗2正確執行,而視窗1報錯,sqlserver在兩個事務發生死鎖的時候,選擇了乙個事務作為犧牲品,這個選擇是隨機的。

通過 set deadlock_priority 《級別》語句可以為事務指定優先級別 ,級別可為low < normal < high,不指定的情況下預設為normal,犧牲品為隨機。當幾個事務相同級別的事務發生死鎖時,隨機放棄事務。

sql server中的 事務

begin tran update data update tb 顧客表 set 郵編 1300511 where 顧客編號 kh003 commit tran update data 在儲存過程中使用事務 判斷pro pro16儲存過程是否存在,如果存在將它刪除 if exists select ...

sqlserver使用select加鎖

sqlserver使用select加鎖 功能說明 holdlock 將共享鎖保留到事務完成,而不是在相應的表 行或資料頁不再需要時就立即釋放鎖。holdlock 等同於 serializable。nolock 不要發出共享鎖,並且不要提供排它鎖。當此選項生效時,可能會讀取未提交的事務或一組在讀取中間...

SQL SERVER中事務的ACID

acid,指資料庫事務正確執行的四個基本要素的縮寫。包含 原子性 atomicity 一致性 consistency 隔離性 isolation 永續性 durability 乙個支援事務 transaction 的資料庫,必需要具有這四種特性,否則在事務過程 transaction process...