當前位置:首頁 » 編程語言 » sql事務死鎖
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

sql事務死鎖

發布時間: 2022-07-17 08:59:01

❶ 怎麼樣解決MSsql產生死鎖的問題

一、 什麼是死鎖
死鎖是指兩個或兩個以上的進程在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去.此時稱系統處於死鎖狀態或系統產生了死鎖,這些永遠在互相等的進程稱為死鎖進程.

二、 死鎖產生的四個必要條件
互斥條件:指進程對所分配到的資源進行排它性使用,即在一段時間內某資源只由一個進程佔用。如果此時還有其它進程請求資源,則請求者只能等待,直至佔有資源的進程用畢釋放
請求和保持條件:指進程已經保持至少一個資源,但又提出了新的資源請求,而該資源已被其它進程佔有,此時請求進程阻塞,但又對自己已獲得的其它資源保持不放
不剝奪條件:指進程已獲得的資源,在未使用完之前,不能被剝奪,只能在使用完時由自己釋放
環路等待條件:指在發生死鎖時,必然存在一個進程——資源的環形鏈,即進程集合{P0,P1,P2,···,Pn}中的P0正在等待一個P1佔用的資源;P1正在等待P2佔用的資源,……,Pn正在等待已被P0佔用的資源
這四個條件是死鎖的必要條件,只要系統發生死鎖,這些條件必然成立,而只要上述條件之一不滿足,就不會發生死鎖。
三、 如何處理死鎖
1) 鎖模式
共享鎖(S)
由讀操作創建的鎖,防止在讀取數據的過程中,其它事務對數據進行更新;其它事務可以並發讀取數據。共享鎖可以加在表、頁、索引鍵或者數據行上。在SQL SERVER默認隔離級別下數據讀取完畢後就會釋放共享鎖,但可以通過鎖提示或設置更高的事務隔離級別改變共享鎖的釋放時間。
2.獨占鎖(X)
對資源獨占的鎖,一個進程獨佔地鎖定了請求的數據源,那麼別的進程無法在此數據源上獲得任何類型的鎖。獨占鎖一致持有到事務結束。
3.更新鎖(U)
更新鎖實際上並不是一種獨立的鎖,而是共享鎖與獨占鎖的混合。當SQL SERVER執行數據修改操作卻首先需要搜索表以找到需要修改的資源時,會獲得更新鎖。
更新鎖與共享鎖兼容,但只有一個進程可以獲取當前數據源上的更新鎖,
其它進程無法獲取該資源的更新鎖或獨占鎖,更新鎖的作用就好像一個序列化閥門(serialization gate),將後續申請獨占鎖的請求壓入隊列中。持有更新鎖的進程能夠將其轉換成該資源上的獨占鎖。更新鎖不足以用於更新數據—實際的數據修改仍需要用到獨占鎖。對於獨占鎖的序列化訪問可以避免轉換死鎖的發生,更新鎖會保留到事務結束或者當它們轉換成獨占鎖時為止。
4. 意向鎖(IX,IU,IS)
意向鎖並不是獨立的鎖定模式,而是一種指出哪些資源已經被鎖定的機制。
如果一個表頁上存在獨占鎖,那麼另一個進程就無法獲得該表上的共享表鎖,這種層次關系是用意向鎖來實現的。進程要獲得獨占頁鎖、更新頁鎖或意向獨占頁鎖,首先必須獲得該表上的意向獨占鎖。同理,進程要獲得共享行鎖,必須首先獲得該表的意向共享鎖,以防止別的進程獲得獨占表鎖。
5. 特殊鎖模式(Sch_s,Sch_m,BU)
SQL SERVER提供3種額外的鎖模式:架構穩定鎖、架構修改鎖、大容量更新鎖。
6.轉換鎖(SIX,SIU,UIX)
轉換鎖不會由SQL SERVER 直接請求,而是從一種模式轉換到另一種模式所造成的。SQL SERVER 2008支持3種類型的轉換鎖:SIX、SIU、UIX.其中最常見的是SIX鎖,如果事務持有一個資源上的共享鎖(S),然後又需要一個IX鎖,此時就會出現SIX。
7.鍵范圍鎖
鍵范圍鎖是在可序列化隔離級別中鎖定一定范圍內數據的鎖。保證在查詢數據的鍵范圍內不允許插入數據。
http://www.cnblogs.com/qiaokai/p/5344252.html

❷ MSSQL事務死鎖的問題

死鎖 發生在 2個 會話, 互相鎖定對方資源的情況下。

例如你的 一個事務X,事務當中有DELETE表A的命令 , 完成 DELETE A 之後, 又執行 UPDATE B

而另外有一個事務Y, 事務時 先 UPDATE B , 然後 DELETE A.

那麼這種情況下, 可能會發生死鎖。

如果大家都是 DELETE A , 沒有其他額外操作的話。

那麼 第一個 線程, 執行 DELETE A 的過程中, 後續的線程, 會卡一下, 等待 第一個線程執行完畢。 然後再接著執行。 而不是死鎖。

❸ sql server死鎖的進程怎麼處理

怎麼解除SQL Server死鎖的問題?SQL Server死鎖是我們經常會碰到的問題,下面就為您介紹如何查詢SQL Server死鎖,希望對您學習SQL Server死鎖方面能有所幫助。   
SQL Server死鎖的查詢方法:    exec master.dbo.p_lockinfo 0,0 ---顯示死鎖的進程,不顯示正常的進程    exec master.dbo.p_lockinfo 1,0 ---殺死死鎖的進程,不顯示正常的進程.   
SQL Server死鎖的解除方法:    Create proc p_lockinfo    @kill_lock_spid bit=1, --是否殺掉死鎖的進程,1 殺掉, 0 僅顯示    @show_spid_if_nolock bit=1 --如果沒有死鎖的進程,是否顯示正常進程信息,1 顯示,0 不顯示    as    declare @count int,@s nvarchar(1000),@i int    select id=identity(int,1,1),標志,    進程ID=spid,線程ID=kpid,塊進程ID=blocked,資料庫ID=dbid,   
資料庫名=db_name(dbid),用戶ID=uid,用戶名=loginame,累計CPU時間=cpu,    登陸時間=login_time,打開事務數=open_tran, 進程狀態=status,    工作站名=hostname,應用程序名=program_name,工作站進程ID=hostprocess,    域名=nt_domain,網卡地址=net_address    into #t from(    select 標志='死鎖的進程',    spid,kpid,a.blocked,dbid,uid,loginame,cpu,login_time,open_tran,    status,hostname,program_name,hostprocess,nt_domain,net_address,   
s1=a.spid,s2=0    from mastersysprocesses a join (    select blocked from mastersysprocesses group by blocked    )b on a.spid=b.blocked where a.blocked=0    union all    select '|_犧牲品_>',    spid,kpid,blocked,dbid,uid,loginame,cpu,login_time,open_tran,    status,hostname,program_name,hostprocess,nt_domain,net_address,    s1=blocked,s2=1    from mastersysprocesses a where blocked<>0    )a order by s1,s2    select @count=@@rowcount,@i=1    if @count=0 and @show_spid_if_nolock=1    begin    insert #t    select 標志='正常的進程',    spid,kpid,blocked,dbid,db_name(dbid),uid,loginame,cpu,login_time,    open_tran,status,hostname,program_name,hostprocess,nt_domain,net_address    from mastersysprocesses    set @count=@@rowcount    end    if @count>0    begin    create table #t1(id int identity(1,1),a nvarchar(30),b Int,EventInfo nvarchar(255))    if @kill_lock_spid=1    begin    declare @spid varchar(10),@標志 varchar(10)    while @i<=@ count    begin    select @spid=進程ID,@標志=標志 from #t whereid=@ i    insert #t1 exec('dbcc inputbuffer(')')    if @標志='死鎖的進程' exec('kill'+@ spid)    set @i=@i+1    end    end    else    while @i<=@ count    begin    select @s='dbcc inputbuffer('+cast(進程ID as varchar)+')' from #t whereid=@ i    insert #t1 exec(@s)    set @i=@i+1    end    select a.*,進程的SQL語句=b.EventInfo    from #t a join #t1 b on a.id=b.id    end

❹ 怎麼查看和處理SQL死鎖

找到事務號,可以從 events_statements_current 找到對應的 SQL 語句:
SQL_TEXT: delete from action1 where id = 3 //具體的sql語句
DIGEST:
DIGEST_TEXT: DELETE FROM `action1` WHERE `id` = ?
CURRENT_SCHEMA: test1
OBJECT_TYPE: NULL
OBJECT_SCHEMA: NULL
OBJECT_NAME: NULL
OBJECT_INSTANCE_BEGIN: NULL
MYSQL_ERRNO: 0
RETURNED_SQLSTATE: 00000
MESSAGE_TEXT: NULL
ERRORS: 0
WARNINGS: 0
ROWS_AFFECTED: 1
ROWS_SENT: 0
ROWS_EXAMINED: 3
CREATED_TMP_DISK_TABLES: 0
CREATED_TMP_TABLES: 0
SELECT_FULL_JOIN: 0
SELECT_FULL_RANGE_JOIN: 0
SELECT_RANGE: 0
SELECT_RANGE_CHECK: 0
SELECT_SCAN: 0
SORT_MERGE_PASSES: 0
SORT_RANGE: 0
SORT_ROWS: 0
SORT_SCAN: 0
NO_INDEX_USED: 0
NO_GOOD_INDEX_USED: 0
NESTING_EVENT_ID: NULL
NESTING_EVENT_TYPE: NULL
NESTING_EVENT_LEVEL: 0
1 row in set (0.00 sec)

可以看到是一條 delete 阻塞了後續的 update,生產環境中可以拿著這條 SQL 語句詢問開發,是不是有 kill 的必要。

❺ 怎麼解決sql server資料庫死鎖

1
編程的時候對死鎖多加註意,相應增加代碼解決
2
實際使用時,可以手工從sql管理器裡面解鎖
3
因為頁面級鎖第一個程序打開頁面操作,馬上就關閉的話,後面再打開就不會引起鎖定了。所以主要是程序編寫不完善出現的,SQL語句造成的少之又少。

❻ sql server 事務造成死鎖怎麼辦

解鎖唄

USE [master]
DECLARE @cmdKill VARCHAR(50)
DECLARE killCursor CURSOR FOR
SELECT 'KILL ' + Convert(VARCHAR(5), p.spid)
FROM master.dbo.sysprocesses AS p
WHERE p.dbid = db_id('auth_ldjt')
OPEN killCursor
FETCH killCursor INTO @cmdKill
WHILE 0 = @@fetch_status
BEGIN
EXECUTE (@cmdKill)
FETCH killCursor INTO @cmdKill
END
CLOSE killCursor
DEALLOCATE killCursor

❼ sql進程死鎖

你的兩個問題的回答是肯定的。
rs.Open是單純打開結果集,是讀操作,一般不會死鎖;
另外一個問題,Update的速度是比rs.Open要快,因為Update的數據傳遞量少,而且基本上是單向操作,就是發送指令到資料庫伺服器,然後在伺服器側運行;而rs.Open不但要發送查詢指令到資料庫伺服器,還要把產生的結果集返回到客戶端,網路流量大,需要的時間要多。

❽ sql死鎖的原因及解決方法

在事務中在修改A表的時候沒有結束事務又要讀取A表的數據。導致自己等自己。變成死鎖。
解決方法很簡單,KILL掉就行。
程序上要先selet後update或者insert