Oracle數(shù)據(jù)庫出現(xiàn)死鎖的時(shí)候可以按照以下處理步驟加以解決:
成都創(chuàng)新互聯(lián)主要為客戶提供服務(wù)項(xiàng)目涵蓋了網(wǎng)頁視覺設(shè)計(jì)、VI標(biāo)志設(shè)計(jì)、全網(wǎng)整合營銷推廣、網(wǎng)站程序開發(fā)、HTML5響應(yīng)式網(wǎng)站建設(shè)、手機(jī)網(wǎng)站開發(fā)、微商城、網(wǎng)站托管及成都網(wǎng)站維護(hù)、WEB系統(tǒng)開發(fā)、域名注冊、國內(nèi)外服務(wù)器租用、視頻、平面設(shè)計(jì)、SEO優(yōu)化排名。設(shè)計(jì)、前端、后端三個(gè)建站步驟的完善服務(wù)體系。一人跟蹤測試的建站服務(wù)標(biāo)準(zhǔn)。已經(jīng)為成都服務(wù)器托管行業(yè)客戶提供了網(wǎng)站建設(shè)服務(wù)。
第一步:嘗試在sqlplus中通過sql命令進(jìn)行刪除,如果能夠刪除成功,則萬事大吉!但通常情況下,出現(xiàn)死鎖時(shí),想通過命令行或者通過Oracle的管理工具刪除有死鎖的session,oracle只會(huì)將該session標(biāo)記為killed,但無法清除掉,往往需要通過第二步在操作系統(tǒng)層級進(jìn)行刪除!
Connected?to?Oracle9i?Enterprise?Edition?Release?9.2.0.1.0?
Connected?as?quik
SQL?select?xidusn,?object_id,?session_id,?locked_mode?from?v$locked_object;?--查死鎖的對象,獲取其SESSION_ID
XIDUSN?OBJECT_ID?SESSION_ID?LOCKED_MODE
----------?----------?----------?-----------
10?30724?29?3
10?30649?29?3
SQL?select?username,sid,serial#?from?v$session?where?sid=29;?--根據(jù)上步獲取到的sid查看其serial#號
USERNAME?SID?SERIAL#
------------------------------?----------?----------
QUIK?29?57107
SQL?alter?system?kill?session?'29,57107';?--刪除進(jìn)程,如已經(jīng)刪除過,則會(huì)報(bào)ora-00031的錯(cuò)誤;否則oracle會(huì)將該session標(biāo)記為killed狀態(tài),等待一段時(shí)間看能否會(huì)自動(dòng)消失,如長時(shí)間消失不掉,則需要做后續(xù)步驟
alter?system?kill?session?'29,57107'
ORA-00031:?session?marked?for?kill
SQL?select?pro.spid?from?v$session?ses,v$process?pro?where?ses.sid=29?and?ses.paddr=pro.addr;?--查看spid號,以便在操作系統(tǒng)中根據(jù)該進(jìn)程號刪除進(jìn)程
SPID
------------
2273286
第二步:進(jìn)入操作系統(tǒng)進(jìn)行刪除進(jìn)程,本示例的操作系統(tǒng)是IBM aix。
login:?root?--錄入用戶名
root's?Password:?--錄入密碼
*******************************************************************************
*?*
*?*
*?Welcome?to?AIX?Version?5.3!?*
*?*
*?*
*?Please?see?the?README?file?in?/usr/lpp/bos?for?information?pertinent?to?*
*?this?release?of?the?AIX?Operating?System.?*
*?*
*?*
*******************************************************************************
Last?unsuccessful?login:?Fri?Apr?23?14:42:57?BEIDT?2010?on?/dev/pts/1?from?10.73
.52.254
Last?login:?Fri?Apr?23?15:27:50?BEIDT?2010?on?/dev/pts/2?from?10.73.52.254
#?ps?-ef|grep?2273286?--查看進(jìn)程詳情
root?2289864?2494636?0?17:07:15?pts/1?0:00?grep?2273286
oracle?2273286?1?0?14:38:24?-?0:21?oracleQUIK?(LOCAL=NO)
#?kill?-9?2273286?--刪除進(jìn)程,小心操作,別寫錯(cuò)進(jìn)程號,如果oracle的關(guān)鍵進(jìn)程被刪,數(shù)據(jù)庫會(huì)崩潰的!
#?ps?-ef|grep?2273286?--再次查看
root?2289864?2494636?0?17:07:15?pts/1?0:00?grep?2273286
For?Windows,?at?the?DOS?Prompt:?orakill?sid?spid
For?UNIX?at?the?command?line?kill?–9?spid
。。。。。。。。。。。。。。。。
看你寫的程序有兩點(diǎn)建議:
1.不要在存儲(chǔ)過程里面使用動(dòng)態(tài)語句,看上去完全沒有使用動(dòng)態(tài)語句的必要,動(dòng)態(tài)語句性能要比靜態(tài)語句差好多。
2.ORACLE里面插入,刪除語句并沒有什么行鎖的概念,除非你顯示調(diào)用SELECT FOR UPDATE,否則oracle不會(huì)鎖住行!
建議你先看看下TOM大師的Expert_one-on-one_Oracle ORACLE和SQL SERVER 是有很大差異的!
ORACLE
EBS操作某一個(gè)FORM界面,或者后臺(tái)數(shù)據(jù)庫操作某一個(gè)表時(shí)發(fā)現(xiàn)一直出于"假死"狀態(tài),可能是該表被某一用戶鎖定,導(dǎo)致其他用戶無法繼續(xù)操作
復(fù)制代碼
代碼如下:--鎖表查詢SQLSELECT
object_name,
machine,
s.sid,
s.serial#
FROM
gv$locked_object
l,
dba_objects
o,
gv$session
s
WHERE
l.object_id
=
o.object_id
AND
l.session_id
=
s.sid;
找到被鎖定的表,解鎖
復(fù)制代碼
代碼如下:--釋放SESSION
SQL:
--alter
system
kill
session
'sid,
serial#';
您可能感興趣的文章:mysql
事務(wù)處理及表鎖定深入簡析
這種情況叫死鎖,與網(wǎng)絡(luò)質(zhì)量無關(guān)。
最大的可能就是程序的原因。
如A進(jìn)程修改a表的某條記錄,修改完a表后,會(huì)繼續(xù)修改b表的某條記錄,然后提交事務(wù)。
這個(gè)時(shí)候,B進(jìn)程在修改b表的那條記錄,修改完后要去修改a表的那條記錄,然后提交事務(wù)。
這樣,當(dāng)A修改完a尚未修改b,B修改完b尚未修改a的時(shí)候,就可能出現(xiàn)B進(jìn)程等待A進(jìn)程提交事務(wù),A進(jìn)程又在等待B進(jìn)程提交事務(wù),兩個(gè)進(jìn)程一直在等。
所以死鎖就出現(xiàn)了。
查詢鎖表
SELECT object_name, machine, s.sid, s.serial#
FROM gv$locked_object l, dba_objects o, gv$session s
WHERE l.object_id = o.object_id
AND l.session_id = s.sid;
2解鎖
--釋放SESSION SQL:
--alter system kill session 'sid, serial#';
ALTER system kill session '23, 1647';
3鎖表原因分析
1.對數(shù)據(jù)庫操作update,insert,delete時(shí)候,數(shù)據(jù)庫無法更新,操作等待時(shí)長,操作結(jié)果不發(fā)生改變
2.在程序中,底層(數(shù)據(jù)訪問層)操作時(shí)候,不成功,數(shù)據(jù)庫連接超時(shí),無法操作,或者操作等待時(shí)長等現(xiàn)象
【加鎖的原理】:比如一個(gè)操作在進(jìn)行修改一表,它沒完成,另一個(gè)操作也操作這張表時(shí)候就需要等待,前面操作結(jié)束之后才可進(jìn)行操作。
4鎖表分類以及如何避免鎖表
Oracle鎖表 行級鎖 表級鎖
---- 行被排他鎖定
----在某行的鎖被釋放之前,其他用戶不能修改此行 ----使用 commit 或 rollback 命令釋放鎖
----Oracle 通過使用 INSERT、UPDATE 和 SELECT…FOR UPDATE 語句自動(dòng)獲取行級鎖
SELECT…FOR UPDATE 子句 ―在表的一行或多行上放置排他鎖 ―用于防止其他用戶更新該行
―可以執(zhí)行除更新之外的其他操作
―select * from goods where gid=1001 ―for update of gname;
―只有該用戶提交事務(wù),其他用戶才能夠更新gname
FOR UPDATE WAIT 子句 ―Oracle9i 中的新增功能 ―防止無限期地等待鎖定的行 ―等待間隔必須指定為數(shù)值文字
―等待間隔不能是表達(dá)式、賦值變量或 PL/SQL 變量
―select * from goods where gid=1001 for update of gname wait 3 ―等待用戶釋放更新鎖的時(shí)間為3秒,否則超時(shí)。 ?表級鎖
―保護(hù)表的數(shù)據(jù)
―在多個(gè)用戶同時(shí)訪問數(shù)據(jù)時(shí)確保數(shù)據(jù)的完整性 ―可以設(shè)置為三種模式:共享、共享更新和 排他
語法:lock table table_namein mode; 共享鎖 ―鎖定表
―僅允許其他用戶執(zhí)行查詢操作 ―不能插入、更新和刪除
―多個(gè)用戶可以同時(shí)在同一表中放置此鎖 ―lock table table_name ―in share mode [nowait];
― rollback 和commit 命令釋放鎖 ― nowait 關(guān)鍵字告訴其他用戶不用等待 共享更新鎖
―鎖定要被更新的行
―允許其他用戶同時(shí)查詢、插入、更新未被鎖定的行
―在 SELECT 語句中使用“FOR UPDATE”子句,可以強(qiáng)制使用共享更新鎖 ―允許多個(gè)用戶同時(shí)鎖定表的不同行
加鎖的兩種方法
lock table tab_name in share update mode; select column1,column2 from goods where goods where gid=1001
for update of column1,column2 排他鎖
―與其他兩種鎖相比,排他鎖是限制性最強(qiáng)的表鎖 ―僅允許其他用戶查詢數(shù)據(jù)
―不允許執(zhí)行插入、刪除和更新操作
―在同一時(shí)間僅允許一位用戶在表上放置排他鎖 ―共享鎖與此相反
lock table tab_name in exclusive mode; lock table 表名[ 表名]... in share mode [nowait]
lock table 表名[ 表名]... in exclusive mode [nowait] lock table 表名[ 表名]... in share update mode[nowait]
-----------------------------------------------------------------------------------------------
LOCK Name
LOCK — 在事務(wù)中明確地鎖定一個(gè)表 LOCK [ TABLE ] name
LOCK [ TABLE ] name IN [ ROW | ACCESS ] { SHARE | EXCLUSIVE } MODE
LOCK [ TABLE ] name IN SHARE ROW EXCLUSIVE MODE 輸入
name
要鎖定的現(xiàn)存的表.
ACCESS SHARE MODE
注意: 這個(gè)鎖模式對被查詢的表自動(dòng)生效。
這是最小限制的鎖模式,只與 ACCESS EXCLUSIVE 模式?jīng)_突。 它用于保護(hù)被查詢的表免于被并行的 ALTER TABLE, DROP TABLE 和 VACUUM 對同一表操作的語句修改。
ROW SHARE MODE
注意: 任何 SELECT...FOR UPDATE 語句執(zhí)行時(shí)自動(dòng)生效。 因?yàn)樗且粋€(gè)共享鎖,以后可能更新為 ROW EXCLUSIVE 鎖。
與 EXCLUSIVE 和 ACCESS EXCLUSIVE 鎖模式?jīng)_突。
ROW EXCLUSIVE MODE
注意: 任何 UPDATE, DELETE和 INSERT 語句執(zhí)行時(shí)自動(dòng)生效。
與 SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE 和 ACCESS EXCLUSIVE 模式?jīng)_突。
SHARE MODE
注意: 任何 CREATE INDEX 語句執(zhí)行時(shí)自動(dòng)附加。 共享鎖住整個(gè)表.
與 ROW EXCLUSIVE,SHARE ROW EXCLUSIVE,EXCLUSIVE 和 ACCESS EXCLUSIVE 模式?jīng)_突。這個(gè)模式防止一個(gè)表被并行更新。
SHARE ROW EXCLUSIVE MODE
注意: 這個(gè)模式類似 EXCLUSIVE MODE,但是允許其他事務(wù)的 SHARE ROW 鎖.
-----------------------------------------------------------------------------------------------
與 ROW EXCLUSIVE,SHARE,SHARE ROW EXCLUSIVE,EXCLUSIVE 和 ACCESS EXCLUSIVE 模式?jīng)_突。
EXCLUSIVE MODE
注意: 這個(gè)模式同樣比 SHARE ROW EXCLUSIVE 更有約束力. 它阻塞所有并行的 ROW SHARE/SELECT... FOR UPDATE 查詢。
與 ROW EXCLUSIVE,SHARE,SHARE ROW EXCLUSIVE,EXCLUSIVE 和 ACCESS EXCLUSIVE 模式?jīng)_突。
ACCESS EXCLUSIVE MODE
注意: 由語句 ALTER TABLE, DROP TABLE,VACUUM 執(zhí)行時(shí)自動(dòng)生效。這是最嚴(yán)格的約束鎖,它與所有其他的鎖 模式?jīng)_突并且保護(hù)一個(gè)被鎖定的表不被任何其他并行的操作更改。
注意: 一個(gè)不合格的 LOCK TABLE 同樣要求這個(gè)鎖模式 (例如,一條沒有顯式鎖模式選項(xiàng)的命令)。
輸出
LOCK TABLE 成功鎖定后的返回.
ERROR name: Table does not exist. 如果name 不存在,返回此信息.
描述
LOCK TABLE 控制一次事務(wù)的生命期內(nèi)對某表的并行訪問. Postgres 在可能的情況下盡可能使用最小約束的鎖模式。 LOCK TABLE 在你需要時(shí)提供更有約束力的鎖。
RDBMS 鎖定使用下面術(shù)語:
EXCLUSIVE
排它鎖,防止其他(事務(wù))鎖的產(chǎn)生.
SHARE
允許其他(事務(wù))共享鎖.避免 EXCLUSIVE 鎖.
ACCESS
-----------------------------------------------------------------------------------------------
鎖定表結(jié)構(gòu).
ROW
鎖定獨(dú)立的行.
注意: 如果沒有聲明 EXCLUSIVE 或 SHARE,假設(shè)為 EXCLUSIVE.鎖存在于事務(wù)周期內(nèi).
例如,一個(gè)應(yīng)用在 READ COMMITED 隔離級別上運(yùn)行事務(wù), 并且它需要保證在表中的數(shù)據(jù)在事務(wù)的運(yùn)行過程中都存在。要實(shí)現(xiàn)這個(gè)你 可以在查詢之前對表使用 SHARE 鎖模式進(jìn)行鎖定。這樣將保護(hù)數(shù)據(jù)不被 并行修改并且為任何更進(jìn)一步的對表的讀操作提供實(shí)際狀態(tài)的數(shù)據(jù), 因?yàn)? SHARE 鎖模式與任何寫操作需要的 ROW EXCLUSIVE 模式?jīng)_突,并且你的 LOCK TABLE name IN SHARE MODE 語句將等到所有并行的寫操作提交或回卷后才執(zhí)行。
注意: 當(dāng)在 SERIALIZABLE 隔離級別運(yùn)行事務(wù),而且你需要讀取真實(shí)狀態(tài)的數(shù)據(jù)時(shí), 你必須在執(zhí)行任何 DML 語句 (這時(shí)事務(wù)定義什么樣的并行修改對它自己是可見的) 之前運(yùn)行一個(gè) LOCK TABLE 語句。
除了上面的要求外,如果一個(gè)事務(wù)準(zhǔn)備修改一個(gè)表中的數(shù)據(jù), 那么應(yīng)該使用 SHARE ROW EXCLUSIVE 鎖模式以避免死鎖情況(當(dāng)兩個(gè) 并行的事務(wù)試圖以 SHARE 模式鎖住表然后試圖更改表中的數(shù)據(jù)時(shí), 兩個(gè)事務(wù)(隱含的)都需要 ROW EXCLUSIVE 鎖模式,而此模式與并行的 SHARE 鎖沖突)。
繼續(xù)上面的死鎖(兩個(gè)事務(wù)彼此等待)問題, 你應(yīng)該遵循兩個(gè)通用的規(guī)則以避免死鎖條件:
事務(wù)應(yīng)該以相同的順序?qū)ο嗤膶ο笳埱箧i。
例如,如果一個(gè)應(yīng)用更新行 R1 然后更新行 R2(在同一的事務(wù)里), 那么第二個(gè)應(yīng)用如果稍后要更新行 R1 時(shí)不應(yīng)該更新行 R2(在 同一事務(wù)里)。相反,它應(yīng)該與第一個(gè)應(yīng)用以相同的順序更新行 R1 和 R2。
事務(wù)請求兩個(gè)互相沖突的鎖模式的前提:其中一個(gè)鎖模式是自沖突的 (也就是說,一次只能被一個(gè)事務(wù)持有)。 如果涉及多種鎖模式,那么事務(wù)應(yīng)該總是最先請求最嚴(yán)格的鎖模式。
這個(gè)規(guī)則的例子在前面的關(guān)于用 SHARE ROW EXCLUSIVE 模式取代 SHARE 模式的討論中已經(jīng)給出了。 -----------------------------------------------------------------------------------------------
注意: Postgres 的確檢測死鎖, 并將回卷至少一個(gè)等待的事務(wù)以解決死鎖。
注意
LOCK 是 Postgres 語言擴(kuò)展.
除了ACCESS SHARE/EXCLUSIVE 鎖模式外,所有其他 Postgres 鎖模式和 LOCK TABLE 語句都與那些在 Oracle 里面的兼容。
LOCK 只在事務(wù)內(nèi)部使用.
用法
演示在往一個(gè)外鍵表上插入時(shí)在有主鍵的表上使用 SHARE 的鎖:
BEGIN WORK;
LOCK TABLE films IN SHARE MODE; SELECT id FROM films
WHERE name = 'Star Wars: Episode I - The Phantom Menace';
-- 如果記錄沒有返回則回卷
INSERT INTO films_user_comments VALUES
(_id_, 'GREAT! I was waiting for it for so long!'); COMMIT WORK;
在執(zhí)行刪除操作時(shí)對一個(gè)有主鍵的表進(jìn)行 SHARE ROW EXCLUSIVE 鎖:
BEGIN WORK;
LOCK TABLE films IN SHARE ROW EXCLUSIVE MODE; DELETE FROM films_user_comments WHERE id IN (SELECT id FROM films WHERE rating 5); DELETE FROM films WHERE rating 5; COMMIT WORK; 兼容性 SQL92
在SQL92里面沒有LOCK TABLE ,可以使用 SET TRANSACTION 來聲明當(dāng)前事務(wù)的級別. 我們也支持這個(gè),參閱 SET TRANSACTION 獲取詳細(xì)信息。