萬盛學電腦網

 萬盛學電腦網 >> 數據庫 >> oracle教程 >> Oracle中的數據鎖定機制全面解析

Oracle中的數據鎖定機制全面解析

為了得到最大的性能,一般數據庫都有並發機制,不過帶來的問題就是數據訪問的沖突。為了解決這個問題,大多數數據庫用的方法就是數據的鎖定。

數據的鎖定分為兩種方法,第一種叫做悲觀鎖,第二種叫做樂觀鎖。什麼叫悲觀鎖呢,悲觀鎖顧名思義,就是對數據的沖突采取一種悲觀的態度,也就是說假設數據肯定會沖突,所以在數據開始讀取的時候就把數據鎖定住。而樂觀鎖就是認為數據一般情況下不會造成沖突,所以在數據進行提交更新的時候,才會正式對數據的沖突與否進行檢測,如果發現沖突了,則讓用戶返回錯誤的信息,讓用戶決定如何去做。

先從悲觀鎖開始說。在SqlServer等其余很多數據庫中,數據的鎖定通常采用頁級鎖的方式,也就是說對一張表內的數據是一種串行化的更新插入機制,在任何時間同一張表只會插1條數據,別的想插入的數據要等到這一條數據插完以後才能依次插入。帶來的後果就是性能的降低,在多用戶並發訪問的時候,當對一張表進行頻繁操作時,會發現響應效率很低,數據庫經常處於一種假死狀態。而Oracle用的是行級鎖,只是對想鎖定的數據才進行鎖定,其余的數據不相干,所以在對Oracle表中並發插數據的時候,基本上不會有任何影響。

Oracle的悲觀鎖需要利用一條現有的連接,分成兩種方式,從SQL語句的區別來看,就是一種是for update,一種是for update nowait的形式。比如我們看一個例子。首先建立測試用的數據庫表。

CREATE TABLE TEST
(ID,
NAME,
LOCATION,
VALUE,
CONSTRAINT test_pk PRIMARY KEY(ID))
AS SELECT deptno, dname, loc, 1 FROM scott.dept

這裡我們利用了Oracle的Sample的scott用戶的表,把數據copy到我們的test表中。首先我們看一下for update鎖定方式。首先我們執行如下的select for update語句。

select * from test where id = 10 for update

通過這條檢索語句鎖定以後,再開另外一個sql*plus窗口進行操作,再把上面這條sql語句執行一便,你會發現sqlplus好像死在那裡了,好像檢索不到數據的樣子,但是也不返回任何結果,就屬於卡在那裡的感覺。這個時候是什麼原因呢,就是一開始的第一個Session中的select for update語句把數據鎖定住了。由於這裡鎖定的機制是wait的狀態(只要不表示nowait那就是wait),所以第二個Session(也就是卡住的那個sql*plus)中當前這個檢索就處於等待狀態。當第一個session最後commit或者rollback之後,第二個session中的檢索結果就是自動跳出來,並且也把數據鎖定住。不過如果你第二個session中你的檢索語句如下所示。

select * from test where id = 10

也就是沒有for update這種鎖定數據的語句的話,就不會造成阻塞了。另外一種情況,就是當數據庫數據被鎖定的時候,也就是執行剛才for update那條sql以後,我們在另外一個session中執行for update nowait後又是什麼樣呢。比如如下的sql語句。 由於這條語句中是制定采用nowait方式來進行檢索,所以當發現數據被別的session鎖定中的時候,就會迅速返回ORA-00054錯誤,內容是資源正忙, 但指定以 NOWAIT 方式獲取資源。所以在程序中我們可以采用nowait方式迅速判斷當前數據是否被鎖定中,如果鎖定中的話,就要采取相應的業務措施進行處理。

select * from test where id = 10 for update nowait

那這裡另外一個問題,就是當我們鎖定住數據的時候,我們對數據進行更新和刪除的話會是什麼樣呢。比如同樣,我們讓第一個Session鎖定住id=10的那條數據,我們在第二個session中執行如下語句。

update test set value=2 where id = 10

  • 共3頁:
  • 上一頁
  • 1
  • 2
  • 3
  • 下一頁
copyright © 萬盛學電腦網 all rights reserved