當前位置:首頁 » 數據倉庫 » 資料庫怎麼防止死鎖
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

資料庫怎麼防止死鎖

發布時間: 2022-09-23 14:31:18

A. 在資料庫中解決死鎖的常用方法有哪些

1、要求每個事務一次就將所有要使用的數據全部加鎖,否則不能執行。
2、採用按序加鎖法.預先規定一個封鎖順序,所有的事務都必須按這個順序對數據執行封鎖。
3、不採取任何措施來預防死鎖的發生,而是周期性地檢查系統中是否有死鎖.如果發現死鎖就設法解除。

B. 資料庫死鎖處理方法

mysql資料庫死鎖解決方法如下:

1、對於按鈕等控制項,點擊後使其立刻失效,不讓用戶重復點擊,避免對同時對同一條記錄操作。

2、使用樂觀鎖進行控制。樂觀鎖大多是基於數據版本(Version)記錄機制實現。即為數據增加一個版本標識,在基於資料庫表的版本解決方案中,一般是 通過為資料庫表增加一個「version」欄位來實現。讀取出數據時,將此版本號一同讀出,之後更新時,對此版本號加一。此時,將提交數據的版本數據與數 據庫表對應記錄的當前版本信息進行比對,如果提交的數據版本號大於資料庫表當前版本號,則予以更新,否則認為是過期數據。樂觀鎖機制避免了長事務中的數據 庫加鎖開銷(用戶A和用戶B操作過程中,都沒有對資料庫數據加鎖),大大提升了大並發量下的系統整體性能表現。Hibernate 在其數據訪問引擎中內置了樂觀鎖實現。需要注意的是,由於樂觀鎖機制是在系統中實現,來自外部系統的用戶更新操作不受系統的控制,因此可能會造 成臟數據被更新到資料庫中。

C. 怎麼避免死鎖

什麼是死鎖,如何避免死鎖?
線程A需要資源X,而線程B需要資源Y,而雙方都掌握有對方所要的資源,這種情況稱為死鎖(deadlock),或死亡擁抱(the deadly embrace)。

在並發程序設計中,死鎖 (deadlock) 是一種十分常見的邏輯錯誤。通過採用正確的編程方式,死鎖的發生不難避免。

死鎖的四個必要條件

------------------------------

在計算機專業的本科教材中,通常都會介紹死鎖的四個必要條件。這四個條件缺一不可,或者說只要破壞了其中任何一個條件,死鎖就不可能發生。我們來復習一下,這四個條件是:

互斥(Mutual exclusion):存在這樣一種資源,它在某個時刻只能被分配給一個執行緒(也稱為線程)使用;
持有(Hold and wait):當請求的資源已被佔用從而導致執行緒阻塞時,資源佔用者不但無需釋放該資源,而且還可以繼續請求更多資源;
不可剝奪(No preemption):執行緒獲得到的互斥資源不可被強行剝奪,換句話說,只有資源佔用者自己才能釋放資源;
環形等待(Circular wait):若干執行緒以不同的次序獲取互斥資源,從而形成環形等待的局面,想像在由多個執行緒組成的環形鏈中,每個執行緒都在等待下一個執行緒釋放它持有的資源。
解除死鎖的必要條件
不難看出,在死鎖的四個必要條件中,第二、三和四項條件比較容易消除。通過引入事務機制,往往可以消除第二、三兩項條件,方法是將所有上鎖操作均作為事務對待,一旦開始上鎖,即確保全部操作均可回退,同時通過鎖管理器檢測死鎖,並剝奪資源(回退事務)。這種做法有時會造成較大開銷,而且也需要對上鎖模式進行較多改動。

消除第四項條件是比較容易且代價較低的辦法。具體來說這種方法約定:上鎖的順序必須一致。具體來說,我們人為地給鎖指定一種類似「水位」的方向性屬性。無論已持有任何鎖,該執行緒所有的上鎖操作,必須按照一致的先後順序從低到高(或從高到低)進行,且在一個系統中,只允許使用一種先後次序。

請注意,放鎖的順序並不會導致死鎖。也就是說,盡管按照 鎖A, 鎖B, 放A, 放B 這樣的順序來進行鎖操作看上去有些怪異,但是只要大家都按先A後B的順序上鎖,便不會導致死鎖。

解決方法:

1 使用事務時,盡量縮短事務的邏輯處理過程,及早提交或回滾事務; (細化處理邏輯,執行一段邏輯後便回滾或者提交,然後再執行其它邏輯,直到事物執行完畢提交)
2 設置死鎖超時參數為合理范圍,如:3分鍾-10分種;超過時間,自動放棄本次操作,避免進程懸掛;
3 優化程序,檢查並避免死鎖現象出現;
4 .對所有的腳本和SP都要仔細測試,在正是版本之前。
5 所有的SP都要有錯誤處理(通過@error)
6 一般不要修改SQL SERVER事務的默認級別。不推薦強行加鎖

另外參考的解決方法:

按同一順序訪問對象
如果所有並發事務按同一順序訪問對象,則發生死鎖的可能性會降低。例如,如果兩個並發事務獲得 Supplier 表上的鎖,然後獲得 Part 表上的鎖,則在其中一個事務完成之前,另一個事務被阻塞在 Supplier 表上。第一個事務提交或回滾後,第二個事務繼續進行。不發生死鎖。將存儲過程用於所有的數據修改可以標准化訪問對象的順序。

避免事務中的用戶交互
避免編寫包含用戶交互的事務,因為運行沒有用戶交互的批處理的速度要遠遠快於用戶手動響應查詢的速度,例如答復應用程序請求參數的提示。例如,如果事務正在等待用戶輸入,而用戶去吃午餐了或者甚至回家過周末了,則用戶將此事務掛起使之不能完成。這樣將降低系統的吞吐量,因為事務持有的任何鎖只有在事務提交或回滾時才會釋放。即使不出現死鎖的情況,訪問同一資源的其它事務也會被阻塞,等待該事務完成。

保持事務簡短並在一個批處理中
在同一資料庫中並發執行多個需要長時間運行的事務時通常發生死鎖。事務運行時間越長,其持有排它鎖或更新鎖的時間也就越長,從而堵塞了其它活動並可能導致死鎖。保持事務在一個批處理中,可以最小化事務的網路通信往返量,減少完成事務可能的延遲並釋放鎖。

使用低隔離級別
確定事務是否能在更低的隔離級別上運行。執行提交讀允許事務讀取另一個事務已讀取(未修改)的數據,而不必等待第一個事務完成。使用較低的隔離級別(例如提交讀)而不使用較高的隔離級別(例如可串列讀)可以縮短持有共享鎖的時間,從而降低了鎖定爭奪。

使用綁定連接
使用綁定連接使同一應用程序所打開的兩個或多個連接可以相互合作。次級連接所獲得的任何鎖可以象由主連接獲得的鎖那樣持有,反之亦然,因此不會相互阻塞。

D. SQL SERVER怎樣才能有效避免死鎖

你可以採取以下方法將死鎖減至最少:
•按同一順序訪問對象。
•避免事務中的用戶交互。
•保持事務簡短並處於一個批處理中。
•使用較低的隔離級別。
•使用基於行版本控制的隔離級別。
a.將 READ_COMMITTED_SNAPSHOT 資料庫選項設置為 ON,使得已提交讀事務使用行版本控制。
b.使用快照隔離。
•使用綁定連接。

參考鏈接: https://technet.microsoft.com/zh-cn/library/ms191242%28v=sql.105%29.aspx?f=255&MSPPError=-2147217396

E. 如何防止插入刪除表造成的資料庫死鎖

當系統使用頻繁就會出現插入操作和刪除操作同時進行的情況。這個時候插入事務會先將主表A放置獨占鎖,然後去訪問子表B,而同時刪除事務會對子表B放置獨占鎖,然後去訪問主表A。插入事務會一直獨占著A表,等待訪問B表,刪除事務也一直獨占著B表等待訪問A表,於是兩個事務相互獨佔一個表,等待對方釋放資源,這樣就造成了死鎖。
遇到這種情況我聽說了二種做法:1
刪除A表數據之前,先使用一個事務將B表中相關外鍵指向另外A表中的另外一個數據(比如在A表中專門建一行數據,主鍵設置為0,永遠不會對這行數據執行刪除操作),這樣就消除了要被刪除的數據在AB兩個表中的關系。然後就可以使用刪除事務,先刪除A表中的數據,再刪除B表中的數據,以達到和插入事務表訪問一致,避免死鎖。2
在外鍵關系中,將「刪除規則」設置為「層疊」,這樣刪除事務只需要直接去刪除主表A,而不需要對子表B進行操作。因為刪除規則設置為層疊以後,刪除主表中的數據,子表中所有外鍵關聯的數據也同時刪除了。以上二個解決辦法
1
多了一次更新操作,2還可以
,一般插入時不需要使用事務,刪除時用cascade
插入時可能出現的數據不完整,在讀取時作驗證,不完整數據直接忽略,跑作業定期清理。因為無論插入時使用不使用事務,讀取時都要作驗證以確保數據正確性而不致程序出錯,對應的定期數據清理也是必不可少的,所以並不會因為插入時不使用事務而造成過多的資料庫訪問。用方法2,並規范相關操作的調用,比如通過許可權設定限定刪除操作不會被隨意執行,更大程度上避免誤刪。第2種做法是值得推薦的做法,雖然具有一定性能影響,但是從數據的一致性考慮,是最佳的。
察看死鎖
select
sess.sid,
sess.serial#,
lo.oracle_username,
lo.os_user_name,
ao.object_name,
lo.locked_mode
from
v$locked_object
lo,
dba_objects
ao,
v$session
sess
where
ao.object_id
=
lo.object_id
and
lo.session_id
=
sess.sid
order
by
ao.object_name
;
清除死鎖
alter
system
kill
session
sid,.serial#

F. oracle資料庫如何防止死鎖問題

你好:這個死鎖沒辦法完全避免,盡量的話在做事物提交的時候,提交完成後在進行其餘的同一個表的操作,再就是insert、update等操作盡量能減少就減少。其實正常情況下是很少出現死鎖的。

G. 資料庫死鎖怎麼產生,怎樣能解決

資料庫操作的死鎖是不可避免的,本文並不打算討論死鎖如何產生,重點在於解決死鎖,通過SQL Server 2005, 現在似乎有了一種新的解決辦法。

將下面的SQL語句放在兩個不同的連接裡面,並且在5秒內同時執行,將會發生死鎖。

use Northwind
begin tran
insert into Orders(CustomerId) values(@#ALFKI@#)
waitfor delay @#00:00:05@#
select * from Orders where CustomerId = @#ALFKI@#
commit
print @#end tran@#

SQL Server對付死鎖的辦法是犧牲掉其中的一個,拋出異常,並且回滾事務。在SQL Server 2000,語句一旦發生異常,T-SQL將不會繼續運行,上面被犧牲的連接中, print @#end tran@#語句將不會被運行,所以我們很難在SQL Server 2000的T-SQL中對死鎖進行進一步的處理。

現在不同了,SQL Server 2005可以在T-SQL中對異常進行捕獲,這樣就給我們提供了一條處理死鎖的途徑:

下面利用的try ... catch來解決死鎖。

SET XACT_ABORT ON
declare @r int
set @r = 1
while @r <= 3
begin
begin tran

begin try
insert into Orders(CustomerId) values(@#ALFKI@#)
waitfor delay @#00:00:05@#
select * from Orders where CustomerId = @#ALFKI@#

commit
break
end try

begin catch
rollback
waitfor delay @#00:00:03@#
set @r = @r + 1
continue
end catch
end

解決方法當然就是重試,但捕獲錯誤是前提。rollback後面的waitfor不可少,發生沖突後需要等待一段時間,@retry數目可以調整以應付不同的要求。

但是現在又面臨一個新的問題: 錯誤被掩蓋了,一但問題發生並且超過3次,異常卻不會被拋出。SQL Server 2005 有一個RaiseError語句,可以拋出異常,但卻不能直接拋出原來的異常,所以需要重新定義發生的錯誤,現在,解決方案變成了這樣:

declare @r int
set @r = 1
while @r <= 3
begin
begin tran

begin try
insert into Orders(CustomerId) values(@#ALFKI@#)
waitfor delay @#00:00:05@#
select * from Orders where CustomerId = @#ALFKI@#

commit
break
end try

begin catch
rollback
waitfor delay @#00:00:03@#
set @r = @r + 1
continue
end catch
end
if ERROR_NUMBER() <> 0
begin
declare @ErrorMessage nvarchar(4000);
declare @ErrorSeverity int;
declare @ErrorState int;
select
@ErrorMessage = ERROR_MESSAGE(),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE();
raiserror (@ErrorMessage,
@ErrorSeverity,
@ErrorState
);
end

我希望將來SQL Server 2005能夠直接拋出原有異常,比如提供一個無參數的RaiseError。

因此方案有點臃腫,但將死鎖問題封裝到T-SQL中有助於明確職責,提高高層系統的清晰度。現在,對於DataAccess的代碼,或許再也不需要考慮死鎖問題了。

H. 昆明電腦培訓分享在Java程序中處理資料庫超時與死鎖

每個使用關系型資料庫的程序都可能遇到數據死鎖或不可用的情況,而這些情況需要在代碼中編程來解決;本文主要介紹與資料庫事務死鎖等情況相關的重試邏輯概念,此外,還會探討如何避免死鎖等問題,文章以DB2(版本9)與為例進行講解。



什麼是資料庫鎖定與死鎖


鎖定(Locking)發生在當一個事務獲得對某一資源的「鎖」時,這時,其他的事務就不能更改這個資源了,這種機制的存在是為了保證數據一致性;在設計與資料庫交互的程序時,必須處理鎖與資源不可用的情況。鎖定是個比較復雜的概念,仔細說起來可能又需要一大篇,所以在本文中,只把鎖定看作是一個臨時事件,這意味著如果一個資源被鎖定,它總會在以後某個時間被釋放。而死鎖發生在當多個進程訪問同一資料庫時,其中每個進程擁有的鎖都是其他進程所需的,由此造成每個進程都無法繼續下去。


如何避免鎖


我們可利用事務型資料庫中的隔離級別機制來避免鎖的創建,正確地使用隔離級別可使程序處理更多的並發事件(如允許多個用戶訪問數據),還能預防像丟失修改(Lost Update)、讀「臟」數據(Dirty Read)、不可重復讀(Nonrepeatable Read)及「虛」(Phantom)等問題。


隔離級別 問題現象


丟失修改 讀「臟」數據 不可重復讀 「虛」


可重復讀取 No No No No


讀取穩定性 No No No Yes


游標穩定性 No No Yes Yes


未提交的讀 No Yes Yes Yes


表1:DB2的隔離級別與其對應的問題現象


在只讀模式中,就可以防止鎖定發生,而不用那些未提交只讀隔離級別的含糊語句。昆明電腦培訓http://www.kmbdqn.com/發現一條SQL語句當使用了下列命令之一時,就應該考慮只讀模式了


I. GBase 8s中如何避免死鎖問答

鎖的問題(鎖等待、死鎖)大部分由於沒有正確理解鎖的管理、使用方式導致。要解決鎖的問題,我們可以從如下幾個方面進行嘗試。
1.資料庫鎖資源的設置
ONCONFIG 參數 LOCKS 設置即為資料庫配置數量合適的鎖。通過搜索 online 日誌是否有動態增加鎖的情況:grep 'dynamically allocated' online.log為表設置合理的鎖模式、行級鎖或者頁級鎖。
2.應用程序鎖使用模式設置
通過 onstat -g sql 查看 SESSION 使用的鎖等待模式和隔離級別,要為不同的應用設置合理的隔離級別和鎖等待模式。如在應用程序加入如下語句:
set isolation to dirty read;
set lock mode to wait 5;
3.應用程序避免使用不必要的鎖
許多應用程序的 SQL 語句由於沒有正確地使用索引 INDEX,導致對整個表進行了鎖定,導致並發遇到鎖的問題。需要通過 SQL 優化和創建合理的索引,避免順序掃描帶來的鎖沖突問題。
由於順序掃描導致的鎖等待問題:創建表 test_lock,採用行級鎖,並在 c1 欄位上創建索引,插入 3 行測試數據。
create table test_lock (c1 int,c2 int,c3 char(10)) lock mode row;
create index idx_test_lock on test_lock(c1);
insert into test_lock values(1,1,'abc');
insert into test_lock values(2,2,'abc');
insert into test_lock values(3,3,'abc');
Session 1 通過索引掃描來修改第 2 行記錄:
Begin work;
update test_lock set c3='new' where c1=2;
此時,Session 1 將在第二行記錄上加 X 鎖。
Session 2 通過 c2 欄位以順序掃描的方式來修改第 3 行記錄。
Begin work;
update test_lock set c3='new' where c2=3;
由於 Session 2 採用順序掃描方式,在掃描過程中發現第 2 行記錄加上了 X 鎖,故提示鎖沖突錯誤:
244: Could not do a physical-order read to fetch next row.
107: ISAM error: record is locked.
如果在 c2 欄位上加上索引,或者通過 c1=3 修改第三行記錄,那麼就不會出現鎖的問題。
4.應用程序優化避免過長佔用鎖
鎖是一個公共資源,需要盡快釋放鎖資源,減少等待,如果每個事務都可以在微秒級別完成,那麼鎖就不會是我們關注的問題,減少鎖佔用的時間也是解決鎖問題的關鍵。我們可以通過避免大事務,把大事務拆分多次提交,這樣鎖就能盡快釋放。另外,優化應用的處理性能,如合理使用索引等,都可以加快事務的處理速度,可無形中解決鎖沖突的可能性。
5.設置合理的隔離級別
不同的隔離級別對鎖的使用不一樣,設置合理的隔離級別,可以提高應用程序的並發性,提高系統的處理能力,減少鎖的沖突情況,避免讀操作帶來的鎖問題。