oracle數(shù)據(jù)庫分行級鎖和表級鎖。用select * from table-name for update完成行級鎖。用delete或update完成表級鎖。你鎖定的資源 別人會等待你的提交語句或回退語句完成以后再繼續(xù)進行。
成都創(chuàng)新互聯(lián)是一家專業(yè)提供昌黎企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站設(shè)計、網(wǎng)站制作、H5技術(shù)、小程序制作等業(yè)務(wù)。10年已為昌黎眾多企業(yè)、政府機構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)絡(luò)公司優(yōu)惠進行中。
1、生成Kill Session語句
select?'alter?system?kill?session?'''?||?SID?||','?||?SERIAL#?||?''';'?from
(
select?distinct?a.sid,?a.Serial#,?status,?machine,?LOCKWAIT,?logon_time
from?v$session?a,?v$locked_object?b
where?(a.status?=?'ACTIVE'?or?a.status?=?'INACTIVE')
and?a.sid?=?b.session_id
and?b.ORACLE_USERNAME='XYHISTEST'--加上用戶名是避免把其他系統(tǒng)的會話也關(guān)閉,以免傷及無辜
)
2、批量執(zhí)行第一步生成的語句
alter?system?kill?session?'sid,serial#';
--alter?system?kill?session?'6976,33967';
3、查詢oracle用戶名,機器名,鎖表對象
SELECT?l.session_id?sid,?s.serial#,?l.locked_mode,l.oracle_username,
l.os_user_name,s.machine,?s.terminal,?o.object_name,?s.logon_time
FROM?v$locked_object?l,?all_objects?o,?v$session?s
WHERE?l.object_id?=?o.object_id
AND?l.session_id?=?s.sid
ORDER?BY?sid,?s.serial#?;
/*或者
select?s.SID,?s.OSUSER,?p.spid?as?OSPID,?s.MACHINE,?s.TERMINAL,?s.PROGRAM
from?v$session?s,?v$process?p
where?s.sid?=?6??--session_id
and?s.paddr?=?p.addr;
*/
4、查詢是執(zhí)行何sql語句導(dǎo)致鎖表的
select?b.sql_text
from?v$session?a,?v$sql?b
where?a.sid?=?6?--session_id
and?a.SQL_ADDRESS?=?b.ADDRESS(+);
/*--或者
SELECT?l.session_id?sid,?s.serial#,?l.locked_mode,?l.oracle_username,?s.user#,
l.os_user_name,s.machine,?s.terminal,a.sql_text,?a.action
FROM?v$sqlarea?a,v$session?s,?v$locked_object?l
WHERE?l.session_id?=?s.sid
AND?s.prev_sql_addr?=?a.address
ORDER?BY?sid,?s.serial#;
*/
1.創(chuàng)建測試表,如下圖。
createtabletest_lock(idnumber,valuevarchar2(200));
2.執(zhí)行append語句;并且不做提交,insert/*+append*/intotest_lockvalues(1,1)如下圖。
3.再次執(zhí)行清表語句,truncatetabletest_lock;報鎖表錯誤,如下圖。
4.查看鎖表語句,發(fā)現(xiàn)被鎖表
selectb.object_name,t.*
fromv$locked_objectt,user_objectsb
wheret.object_id=b.object_id
注意事項:
簡化數(shù)據(jù):可以將復(fù)雜的查詢創(chuàng)建為其他人可以使用的視圖,而不必了解復(fù)雜的業(yè)務(wù)或邏輯關(guān)系。這簡化并掩蓋了視圖用戶數(shù)據(jù)的復(fù)雜性。
表結(jié)構(gòu)設(shè)計的補充:在設(shè)計的系統(tǒng)才剛剛開始,大部分的程序直接訪問數(shù)據(jù)表結(jié)構(gòu),但是隨著業(yè)務(wù)的變化,系統(tǒng)更新,等等,引起了一些表結(jié)構(gòu)不適用,這次修改系統(tǒng)的表結(jié)構(gòu)太大,開發(fā)成本較高的影響。
這個時候可以創(chuàng)建一個視圖來補充表結(jié)構(gòu)設(shè)計,降低開發(fā)成本。程序可以通過查詢視圖直接獲得它想要的數(shù)據(jù)。
添加安全性:視圖可以向用戶顯示表中的指定字段,而不是向用戶顯示表中的所有字段。在實際開發(fā)中,視圖通常作為提供數(shù)據(jù)的一種方式提供,并將只讀權(quán)限提供給第三方以供查詢使用。
這種情況叫死鎖,與網(wǎng)絡(luò)質(zhì)量無關(guān)。
最大的可能就是程序的原因。
如A進程修改a表的某條記錄,修改完a表后,會繼續(xù)修改b表的某條記錄,然后提交事務(wù)。
這個時候,B進程在修改b表的那條記錄,修改完后要去修改a表的那條記錄,然后提交事務(wù)。
這樣,當(dāng)A修改完a尚未修改b,B修改完b尚未修改a的時候,就可能出現(xiàn)B進程等待A進程提交事務(wù),A進程又在等待B進程提交事務(wù),兩個進程一直在等。
所以死鎖就出現(xiàn)了。
在對指定表做append操作,其他再做truncate時候,會產(chǎn)生鎖表,如下驗證步驟,
1、創(chuàng)建測試表,
create table test_lock(id number, value varchar2(200));
2、執(zhí)行append語句;并且不做提交,insert /*+append*/ into test_lock values(1,1);
3、再次執(zhí)行清表語句,truncate table test_lock;報鎖表錯誤,
4、查看鎖表語句,發(fā)現(xiàn)被鎖表,
select b.object_name, t.*
from v$locked_object t, user_objects b
where t.object_id = b.object_id
一些ORACLE中的進程被殺掉后,狀態(tài)被置為"killed",但是鎖定的資源很長時間不釋放,有時實在沒辦法,只好重啟數(shù)據(jù)庫。現(xiàn)在提供一種方法解決這種問題,那就是在ORACLE中殺不掉的,在OS一級再殺。
1.下面的語句用來查詢哪些對象被鎖:
select object_name,machine,s.sid,s.serial#
from v$locked_object l,dba_objects o ,v$session s
where l.object_id = o.object_id and l.session_id=s.sid;
2.下面的語句用來殺死一個進程:
alter system kill session '24,111'; (其中24,111分別是上面查詢出的sid,serial#)
【注】以上兩步,可以通過Oracle的管理控制臺來執(zhí)行。
3.如果利用上面的命令殺死一個進程后,進程狀態(tài)被置為"killed",但是鎖定的資源很長時間沒有被釋放,那么可以在os一級再殺死相應(yīng)的進程(線程),首先執(zhí)行下面的語句獲得進程(線程)號:
select spid, osuser, s.program
from v$session s,v$process p
where s.paddr=p.addr and s.sid=24 (24是上面的sid)
4.在OS上殺死這個進程(線程):
1)在unix上,用root身份執(zhí)行命令:
#kill -9 12345(即第3步查詢出的spid)
2)在windows(unix也適用)用orakill殺死線程,orakill是oracle提供的一個可執(zhí)行命令,語法為:
orakill sid thread
其中:
sid:表示要殺死的進程屬于的實例名
thread:是要殺掉的線程號,即第3步查詢出的spid。
例:c:orakill orcl 12345