答案是B,更新鎖!解答如下:
共享鎖
共享 (S) 鎖允許並發事務讀取 (SELECT) 一個資源。資源上存在共享 (S) 鎖時,任何其它事務都不能修改數據。一旦已經讀取數據,便立即釋放資源上的共享 (S) 鎖,除非將事務隔離級別設置為可重復讀或更高級別,或者在事務生存周期內用鎖定提示保留共享 (S) 鎖。
更新鎖
更新 (U) 鎖可以防止通常形式的死鎖。一般更新模式由一個事務組成,此事務讀取記錄,獲取資源(頁或行)的共享 (S) 鎖,然後修改行,此操作要求鎖轉換為排它 (X) 鎖。如果兩個事務獲得了資源上的共享模式鎖,然後試圖同時更新數據,則一個事務嘗試將鎖轉換為排它 (X) 鎖。共享模式到排它鎖的轉換必須等待一段時間,因為一個事務的排它鎖與其它事務的共享模式鎖不兼容;發生鎖等待。第二個事務試圖獲取排它 (X) 鎖以進行更新。由於兩個事務都要轉換為排它 (X) 鎖,並且每個事務都等待另一個事務釋放共享模式鎖,因此發生死鎖。
若要避免這種潛在的死鎖問題,請使用更新 (U) 鎖。一次只有一個事務可以獲得資源的更新 (U) 鎖。如果事務修改資源,則更新 (U) 鎖轉換為排它 (X) 鎖。否則,鎖轉換為共享鎖。
排它鎖
排它 (X) 鎖可以防止並發事務對資源進行訪問。其它事務不能讀取或修改排它 (X) 鎖鎖定的數據。
意向鎖
意向鎖表示 SQL Server 需要在層次結構中的某些底層資源上獲取共享 (S) 鎖或排它 (X) 鎖。例如,放置在表級的共享意向鎖表示事務打算在表中的頁或行上放置共享 (S) 鎖。在表級設置意向鎖可防止另一個事務隨後在包含那一頁的表上獲取排它 (X) 鎖。意向鎖可以提高性能,因為 SQL Server 僅在表級檢查意向鎖來確定事務是否可以安全地獲取該表上的鎖。而無須檢查表中的每行或每頁上的鎖以確定事務是否可以鎖定整個表。
意向鎖包括意向共享 (IS)、意向排它 (IX) 以及與意向排它共享 (SIX)。
2. 在sql中如何退出while死循環
在sql中如何退出while死循環 和其它的語言沒有太大的區別,
牢記循環三要素:循環變數的初始化,循環變數的變更,循環任務
避免死循環是要不要忘記 循環變數的變更
參考代碼:
DECLARE
num1 number;
maxstuid number;
age number;
begin
num1 := 1;
WHILE num1 <= 100 LOOP
--獲取最大的stuid
select max(stuid) + 1 into maxstuid from whilestu1;
--dbms_output.put_line(maxstuid);
if maxstuid is null then
maxstuid := 1;
--dbms_output.put_line('r');
end if;
age := ROUND(DBMS_RANDOM.VALUE(18, 40), 0);
--插入數據
insert into whilestu1
(stuid, stuName, age)
values
(maxstuid, '學員' || cast(maxstuid as varchar2(50)), age);
commit;
num1 := num1 + 1;
END LOOP;
end;
3. sql如何防止死鎖
用事務。transaction
4. 怎麼樣解決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
5. SQL 進程死鎖
首先,需要把你的AutoCommit=TRUE,然後,這是一個編程習慣問題,在pb中,對於數據窗口的操作,首先設置數據窗口的提交方式,我一直
採用 key columns,use
update,然後記得在每次連接完成後,記得及時釋放,譬如,在retrieve完成後,記得及時利用resetupdate()清除數據狀態,然後,
再每次資料庫更新,也就是update()後,記得利用
ll_num1=.update()
if ll_num=1 then
commit;
dw_free.resetupdate( )
else
rollback;
messagebox("提示!","數據保存失敗! ")
end if
以上說法我不贊同:
1、首先AutoCommit=TRUE,以後執行delete,update,insert語句都相當執行了commit,如果是把幾個SQL語句當作是一個完整的事務,要不整
體成功提交,要不rollback,這就寫就不會得到正確的結果。
2、其次key columns,use update,要具體情況具體使用,這種形式的並發性最差,適合對數據的並發性要求不高的場合。
3、再次程序的死鎖原因是多方面的,上述兩個方面只是其中的原因罷了,具體情況具體分析,例如數據盡快提交、建立合理的索引、合理的SQ
L語句、避免交叉事務、對於數據量龐大的表,應及時轉移到歷史庫,我想可以很大程度上避免死鎖。
以上愚見,歡迎拍磚。
在MSSQL控制台中,管理-當前活動-鎖/進程ID看看是那幾個進程在死鎖,然後在進程信息中將這些死鎖的進程殺死/
對查詢進行優化
也建議檢查:外鍵建立索引,如果上索引,再調試下網路
對外鍵建索引可以緩解這個問題。
如在商品字典和銷售明細表中,銷售明細表中商品編號是外鍵,如果在銷售明細表的商品編號上沒有索引,update商品字典會造成銷售明細表
整表鎖表。
解決Sybase資料庫死鎖的方法
人民銀行吉林市中心支行科技處 劉志明
在聯機事務處理(OLTP)的資料庫應用系統中,多用戶、多任務的並發性是系統最重要的技術指標之一。為了提高並發性,目前大部分RDBMS都采
用加鎖技術。然而由於現實環境的復雜性,使用加鎖技術又不可避免地產生了死鎖問題。因此如何合理有效地使用加鎖技術,最小化死鎖是開
發聯機事務處理系統的關鍵。
死鎖產生的原因
在聯機事務處理系統中,造成死機主要有兩方面原因。一方面,由於多用戶、多任務的並發性和事務的完整性要求,當多個事務處理對多個資
源同時訪問時,若雙方已鎖定一部分資源但也都需要對方已鎖定的資源時,無法在有限的時間內完全獲得所需的資源,就會處於無限的等待狀
態,從而造成其對資源需求的死鎖。
另一方面,資料庫本身加鎖機制的實現方法不同,各資料庫系統也會產生其特殊的死鎖情況。如在Sybase SQL Server 11中,最小鎖為2K一頁
的加鎖方法,而非行級鎖。如果某張表的記錄數少且記錄的長度較短(即記錄密度高,如應用系統中的系統配置表或系統參數表就屬於此類表)
,被訪問的頻率高,就容易在該頁上產生死鎖。
幾種死鎖情況及解決方法
清算應用系統中,容易發生死鎖的幾種情況如下:
● 不同的存儲過程、觸發器、動態SQL語句段按照不同的順序同時訪問多張表;
● 在交換期間添加記錄頻繁的表,但在該表上使用了非群集索引(non-clustered);
● 表中的記錄少,且單條記錄較短,被訪問的頻率較高;
● 整張表被訪問的頻率高(如代碼對照表的查詢等)。
以上死鎖情況的對應處理方法如下:
● 在系統實現時應規定所有存儲過程、觸發器、動態SQL語句段中,對多張表的操作總是使用同一順序。如:有兩個存儲過程proc1、proc2,
都需要訪問三張表zltab、z2tab和z3tab,如果proc1按照zltab、z2tab和z3tab的順序進行訪問,那麼,proc2也應該按照以上順序訪問這三張
表。
● 對在交換期間添加記錄頻繁的表,使用群集索引(clustered),以減少多個用戶添加記錄到該表的最後一頁上,在表尾產生熱點,造成死鎖
。這類表多為往來賬的流水表,其特點是在交換期間需要在表尾追加大量的記錄,並且對已添加的記錄不做或較少做刪除操作。
● 對單張表中記錄數不太多,且在交換期間select或updata較頻繁的表可使用設置每頁最大行的辦法,減少數據在表中存放的密度,模擬行級
鎖,減少在該表上死鎖情況的發生。這類表多為信息繁雜且記錄條數少的表。
如:系統配置表或系統參數表。在定義該表時添加如下語句:
with max_rows_per_page=1
● 在存儲過程、觸發器、動態SQL語句段中,若對某些整張表select操作較頻繁,則可能在該表上與其他訪問該表的用戶產生死鎖。對於檢查
賬號是否存在,但被檢查的欄位在檢查期間不會被更新等非關鍵語句,可以採用在select命令中使用at isolation read uncommitted子句的方
法解決。該方法實際上降低了select語句對整張表的鎖級別,提高了其他用戶對該表操作的並發性。在系統高負荷運行時,該方法的效果尤為
顯著。
例如:
select*from titles at isolation read uncommitted
● 對流水號一類的順序數生成器欄位,可以先執行updata流水號欄位+1,然後再執行select獲取流水號的方法進行操作。
小結
筆者對同城清算系統進行壓力測試時,分別對採用上述優化方法和不採用優化方法的兩套系統進行測試。在其他條件相同的情況下,相同業務
筆數、相同時間內,死鎖發生的情況如下:
採用優化方法的系統: 0次/萬筆業務;
不採用優化方法的系統:50~200次/萬筆業務。
所以,使用上述優化方法後,特別是在系統高負荷運行時效果尤為顯著。總之,在設計、開發資料庫應用系統,尤其是OLTP系統時,應該根據
應用系統的具體情況,依據上述原則對系統分別優化,為開發一套高效、可靠的應用系統打下良好的基礎。
經驗:
1:前台問題:檢視代碼查看事物是否被提交或回滾。
2:後台問題:有時候由於處理的問題復雜度高。資料庫日誌空間已滿或不夠
導致事物未能提交。UNIX下的SYBAE就是典型的一例。解決辦法各資料庫廠商有更詳細的說明。
雖然我從9轉到10遇到了好多問題,也浪費了好幾天的時間,但到了現在,我真覺得10比9好。
10沒有了MSSQL專用介面,用的是OLEDB介面,用這個介面一定要注意一個問題是表死鎖的事!
網上講的連接方式都是天下一大抄。
用OLEDB要加上 SQLCA.Lock = "RC",
不然連查詢也會死鎖。
另個一個就是10寫的軟體不再亂碼了,我在繁體寫的軟體在簡體下運行不亂碼,反之也可以。
第三就是編譯速度明顯快很多。
第四就是編譯的時候有了XP樣式皮膚,感覺漂亮多了。
編程要是要養成好習慣,在sql語句insert和update之後,要及時commit,數據窗口update()後也要及時commit;
阻塞是因為多個進程對同一一個資源的訪問沖突,當一個進程排它訪問一個資源時(從進入事務到事務結束為止),當有其他進程需要訪問同
樣的資源時,即造成阻塞(根據鎖的級別和粒度設置);
在實際應用中阻塞可能因為事務沒有提交或者網路速度太慢或者大容量的數據查詢等都可能會造成阻塞。
阻塞可以通過sp_who 系統存儲過程進行查看,執行sp_who 後查看所有blk不等於
0的進程ID(SPID),直到找到SPID在blk列出現,但當前spid 的blk列 =0 即它就是阻塞的源頭。
最簡單的辦法可用 kill spid(源頭進程的SPID值),同時結合sp_lock過程可查看到當前進程的加鎖情況(如鎖的類型被鎖的對象)
最後最重要的是要根據 在查詢到源頭後,使用 DBCC INPUTBUFFER (spid)查看最後一次提交的內容,即可找到因為事務沒有提交造成的阻塞(
一般不能使用 AutoCommit=True,因為大部分MIS程序需要使用批提交,來保證數據的完成性)
http://www.51onnet.com/bbs/forumdisplay.php?f=6
你可能平時編程時沒有注意。在 SQLCA(Transaction)默認情況下 AutoCommit = false(不自動提交)。在同一事務中,如果不提交事務,
可以SELECT、Retrieve,但其它事務(其它計算機的應用程序連接資料庫的事務)就不能。所以導致死鎖,而在單機開發環境看不出來。
你需要在所有的 UPDATE、DELETE 的SQL語句後面,或者數據窗口的Update函數調用之後執行 COMMIT 或 ROLLBACK
死鎖可能存在的原因及解決辦法
一次偶然的機會在論壇上看到一個關於死鎖(其實是阻塞)的帖子,於是把自己的一個小東東拿出來和大家分享,想不到很多人都遇到過這個
問題。
其實解鎖並不是根本的解決辦法,感覺我自己有點誤導大家了,於是有了下面的內容,希望大家能根據自己的應用找出根源,而不是解鎖:
阻塞可能存在的原因及解決方法:
1、事務未提交
這是造成阻塞最常見的原因,因為PB默認是自動啟動事務的,如果你執行了 update,delete ,insert 語句,不執行Commit 則會出現阻塞(
不建議採用自動提交事務的方式,原因在上一帖中交代過),解決的辦法很簡單,查找到所有的修改數據命令(U、I、D)查看是否正常提交,找
到後加入Commit即可;
2、SQL SERVER 沒有正常安裝SP3
對於代碼正常的用戶,仍然出現阻塞,則需要檢查你機器的補丁,特別是WIN2003的機器不安裝補丁,1433都不能監聽;如果沒有安裝補丁
即可(我原來就是被這種情況害過)
3、當然可能你會告訴我,代碼也沒有問題,補丁也裝了,仍然出現可能就需要查看你的機器的CPU和內存的使用率(運行taskmgr),SQL
SERVER 的機器峰值狀態可能出現阻塞,解決的辦法就是出錢:升級伺服器;
4、復雜的查詢或者大容量查詢,比如在查詢中使用多個表的聯合查詢,或者使用 in ,not in 等語句,是非常耗時的,這種解決的辦法稍微復
雜點,需要根據你的應用修改SQL 語句,優化SQL 效率,關於SQL 優化是另外一個復雜的話題,本人也學習中...
能想起的好象就這些了,可能不是很完善,希望有人能補充!
你可能平時編程時沒有注意。在 SQLCA(Transaction)默認情況下 AutoCommit = false(不自動提交)。在同一事務中,如果不提交事務,
可以SELECT、Retrieve,但其它事務(其它計算機的應用程序連接資料庫的事務)就不能。所以導致死鎖,而在單機開發環境看不出來。
你需要在所有的 UPDATE、DELETE 的SQL語句後面,或者數據窗口的Update函數調用之後執行 COMMIT 或 ROLLBACK
補充一點,除了在執行了Update,Delete,Insert需要及時Commit外,在SQL Server中由於使用一個Tempdb的資料庫,這個資料庫是對所有用戶共享
的,當使用了統計類型的SQL函數如:sum,count等,SQL Server會自動使用Tempdb進行暫存統計數據,這樣很容易造成Tempdb被鎖住,所以在讀取了
一個很復雜Store Procere或創建過臨時表後應進行commit,以便釋放Tempdb資源,在retrieved事件中加commit是一個解決辦法,特別是在讀取
報表後更應加,一般報表的Store Procere都比較復雜,在程序中內嵌了SQL游標來讀取數據後也要加commit,我增經試過被鎖住,找了很久才知
6. 在sql中運行的時候一直執行查詢 不出結果是怎麼回事
1. 網路不行
2. 表數據過多,條件限制太少
3. 多表查詢時,表之間的連接條件缺少
7. sql update 語句中怎麼設置那時間不定死
update table set time =getdate()
8. 在sql中如何退出while死循環
1.【格式】
WHILE Boolean_expression
{sql語句|語句塊}
[BREAK]
{sql語句|語句塊}
[CONTINUE]
2.【示例】
DECLARE @s int,@i int
SET @i = 0
SET @s = 0
WHILE @i<=100
BEGIN
SET @s = @s+@i
SET @i = @i+1
END
PRINT 『1+2+…+100=』+CAST(@s AS char(25))
9. 如何查看SQL死鎖
其實所有的死鎖最深層的原因就是一個:資源競爭
表現一:
一個用戶A 訪問表A(鎖住了表A),然後又訪問表B
另一個用戶B 訪問表B(鎖住了表B),然後企圖訪問表A
這時用戶A由於用戶B已經鎖住表B,它必須等待用戶B釋放表B,才能繼續,好了他老人家就只好老老實實在這等了
同樣用戶B要等用戶A釋放表A才能繼續這就死鎖了
解決方法:
這種死鎖是由於你的程序的BUG產生的,除了調整你的程序的邏輯別無他法
仔細分析你程序的邏輯,
1:盡量避免同時鎖定兩個資源
2: 必須同時鎖定兩個資源時,要保證在任何時刻都應該按照相同的順序來鎖定資源.
表現二:
用戶A讀一條紀錄,然後修改該條紀錄
這是用戶B修改該條紀錄
這里用戶A的事務里鎖的性質由共享鎖企圖上升到獨占鎖(for update),而用戶B里的獨占鎖由於A有共享鎖存在所以必須等A釋
放掉共享鎖,而A由於B的獨占鎖而無法上升的獨占鎖也就不可能釋放共享鎖,於是出現了死鎖。
這種死鎖比較隱蔽,但其實在稍大點的項目中經常發生。
解決方法:
讓用戶A的事務(即先讀後寫類型的操作),在select 時就是用Update lock
語法如下:
select * from table1 with(updlock) where ....