Oracle锁表查询和解锁方法

摘要:
Oracle锁表查询和解锁就由解决以下问题来说明在进行批量对DML操作时程序竟然中断了,不再往下执行、查询一下某张表被锁住了,因此不再往下执行了。dba_objects为oracle用户对象及系统对象的集合,通过关联这张表能够获取被锁定对象的详细信息。

数据库操作语句的分类

  • DML:数据操纵语言,关键字:Insert、delete、update
  • DCL:数据库控制语言 ,关键字:grant、remove
  • DQL:数据库查询语言,关键字:select
  • DDL:数据库模式定义语言,关键字:create

oracle表在什么情况下会被锁住

DML锁又可以分为,行锁、表锁、死锁

行锁:当事务执行数据库插入、更新、删除操作时,该事务自动获得操作表中操作行的排它锁。

表级锁:当事务获得行锁后,此事务也将自动获得该行的表锁(共享锁),以防止其它事务进行DDL语句影响记录行的更新。事务也可以在进行过程中获得共享锁或排它锁,只有当事务显示使用LOCK TABLE语句显示的定义一个排它锁时,事务才会获得表上的排它锁,也可使用LOCK TABLE显示的定义一个表级的共享锁(LOCK TABLE具体用法请参考相关文档)。

死锁:当两个事务需要一组有冲突的锁,而不能将事务继续下去的话,就出现死锁。
如事务1在表A行记录#3中有一排它锁,并等待事务2在表A中记录#4中排它锁的释放,而事务2在表A记录行#4中有一排它锁,并等待事务1在表A中记录#3中排它锁的释放,事务1与事务2彼此等待,因此就造成了死锁。死锁一般是因拙劣的事务设计而产生。
死锁只能使用SQL下:alter system kill session “sid,serial#”;或者使用相关操作系统kill进程的命令,如UNIX下kill -9 sid,或者使用其它工具杀掉死锁进程。

DDL锁又可以分为:排它DDL锁、共享DDL锁、分析锁

排它DDL锁:创建、修改、删除一个数据库对象的DDL语句获得操作对象的 排它锁。如使用alter table语句时,为了维护数据的完成性、一致性、合法性,该事务获得一排它DDL锁。

共享DDL锁:需在数据库对象之间建立相互依赖关系的DDL语句通常需共享获得DDL锁。
如创建一个包,该包中的过程与函数引用了不同的数据库表,当编译此包时,该事务就获得了引用表的共享DDL锁。

分析锁:ORACLE使用共享池存储分析与优化过的SQL语句及PL/SQL程序,使运行相同语句的应用速度更快。一个在共享池中缓存的对象获得它所引用数据库对象的分析锁。分析锁是一种独特的DDL锁类型,ORACLE使用它追踪共享池对象及它所引用数据库对象之间的依赖关系。当一个事务修改或删除了共享池持有分析锁的数据库对象时,ORACLE使共享池中的对象作废,下次在引用这条SQL/PLSQL语句时,ORACLE重新分析编译此语句。

Oracle锁表查询和解锁

就由解决以下问题来说明

在进行批量对DML操作时程序竟然中断了,不再往下执行、查询一下某张表被锁住了,因此不再往下执行了。

第一步:通过管理员权限用户查询被锁表信息

如果怀疑表被锁了,或者事务未被正常关闭,在Oracle数据库中我们可以通过以下语句进行查询获取相关信息:

1 select t2.username,
2 t2.sid,
3 t2.serial#,
4 t3.object_name,
5 t2.OSUSER,
6 t2.MACHINE,
7 t2.PROGRAM,
8 t2.LOGON_TIME,
9 t2.COMMAND,
10 t2.LOCKWAIT,
11 t2.SADDR,
12 t2.PADDR,
13 t2.TADDR,
14 t2.SQL_ADDRESS,
15 t1.LOCKED_MODE
16 from v$locked_object t1, v$session t2, dba_objects t3
17  where t1.session_id =t2.sid
18    and t1.object_id =t3.object_id
19  order by t2.logon_time;

大家发现,上面这条SQL语句用到了Oracle的两个视图和一个表,分别是v$locked_object、v$session、dba_objects:
v$locked_object 视图中记录了所有session中的所有被锁定的对象信息。
v$session 视图记录了所有session的相关信息。
dba_objects 为oracle用户对象及系统对象的集合,通过关联这张表能够获取被锁定对象的详细信息。

eg:现在我通过scott用户执行DML语句(eg:select * from emp for update;或者update scott.emp set sal = '2000' where empno='7788'; )之后一直不进行提交,然后通过system用户执行上面的查询oracle中被锁表的sql语句,就会找到如下记录:
Oracle锁表查询和解锁方法第1张

说明:
username:oracle用户名
sid:进程号
serial#:序列号
object_name:表名
osuser:操作系统用户名
machine:机器名
program:操作工具
logon_time:登陆时间
lockwait:表示当前这张表是否正在等待其他用户解锁这张表
locked_mode:锁表模式(下面详细说明)

注意:这时候如果通过system用户执行select * from scott.emp for update;语句就无法成功执行。

第二步:通过拥有管理员权限的用户解除数据库中被锁住的表(SID,SERIAL)

通过第一步查出来的信息找到被锁的表之后执行如下语句解锁该表:

alter system kill session 'sid,seial#';

注意:sid和seial#就是第一步中查询出来的进程号和序列号。

eg:解除第一步中表的锁

alter system kill session '10,15';

现在通过system再次执行DML语句(eg:select * from scott.emp for update;或update scott.emp set sal = '2000' where empno='7788';)就可以了。

锁的模式
v$locked_object中的LOCKED_MODE字段表示锁的模式,oracle中锁的模式有如下几种:
0:none
1:null 空
2:Row-S 行共享(RS):共享表锁,sub share
3:Row-X 行独占(RX):用于行的修改,sub exclusive
4:Share 共享锁(S):阻止其他DML操作,share
5:S/Row-X 共享行独占(SRX):阻止其他事务操作,share/sub exclusive
6:exclusive 独占(X):独立访问使用,exclusive

数字越大锁级别越高, 影响的操作越多。

1级锁有:Select,有时会在v$locked_object出现。
2级锁有:Select for update,Lock For Update,Lock Row Share
select for update当对话使用for update子串打开一个游标时,所有返回集中的数据行都将处于行级(Row-X)独占式锁定,其他对象只能查询这些数据行,不能进行update、delete或select for update操作。
3级锁有:Insert, Update, Delete, Lock Row Exclusive
没有commit之前插入同样的一条记录会没有反应, 因为后一个3的锁会一直等待上一个3的锁, 我们必须释放掉上一个才能继续工作。
4级锁有:Create Index, Lock Share
locked_mode为2,3,4不影响DML(insert,delete,update,select)操作, 但DDL(alter,drop等)操作会提示ora-00054错误。
00054, 00000, “resource busy and acquire with NOWAIT specified”
// *Cause: Resource interested is busy.
// *Action: Retry if necessary.
5级锁有:Lock Share Row Exclusive
具体来讲有主外键约束时update / delete … ; 可能会产生4,5的锁。
6级锁有:Alter table, Drop table, Drop Index, Truncate table, Lock Exclusive

还有一条比较实用的sql:

1 --查某session 正在执行的sql语句,从而可以快速定位到哪些操作或者代码导致事务一直进行没有结束等.
2 SELECT /*+ ORDERED */ 
3 sql_text
4 FROM v$sqltext a
5 WHERE (a.hash_value, a.address) IN
6        (SELECT DECODE(sql_hash_value, 0, prev_hash_value, sql_hash_value),
7                DECODE(sql_hash_value, 0, prev_sql_addr, sql_address)
8 FROM v$session b
9          WHERE b.sid = '67')  /*此处67 为SID*/
10  ORDER BY piece ASC;

免责声明:文章转载自《Oracle锁表查询和解锁方法》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇sass-loader屡次安装不生效的问题Android Activity 切换动画(非原创)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

了解SQL Server锁争用:NOLOCK 和 ROWLOCK 的秘密

http://blog.csdn.net/Atwind/article/details/1832844 关系型数据库,如SQL Server,使用锁来避免多用户修改数据时的并发冲突。当一组数据被某个用户锁定时,除非第一个用户结束修改并释放锁,否则其他用户就无法修改该组数据。 有些数据库,包括SQL Server,用锁来避免用户检索未递交的修改记录。在这...

Thinkphp5 sql注入分析

Thinkphp5 sql注入 影响版本: 5.0.13<=ThinkPHP<=5.0.15 、 5.1.0<=ThinkPHP<=5.1.5 。 0x01漏洞触发点: 导致这个漏洞的函数为Builder类的parseData函数 这个函数的前半段主要作用为获取数据表的字段,然后进入一个循环,我们重点看第二个elseif处 这里...

自主驱动发展 创新引领未来丨第九届数据技术嘉年华大会全议程精彩呈现

简介 时光荏苒,转眼又到了一年一度的总结时刻。第八届数据技术嘉年华大会的精彩演讲还历历在目, 第九届数据技术嘉年华大会在紧锣密鼓的筹备中,即将拉开帷幕。本次大会于2019年11月15日-16日在北京新云南皇冠假日酒店盛大开启,期待现场与大家共畅技术之美。 2019年,对于数据库行业,注定是不平凡的一年。在墨天轮数据库流行度的排行榜上,Oracle 依旧保持...

[UWP小白日记2]SQLite数据库DOME

  数据库说简单点就是增删改查,但是对新手来说也是要爆肝的。作为一个新手爆肝无数次啊, 血的教训啊现在UWP的教程又少,说多了都是泪。留下来免得以后又爆肝。还有:一定要写注释!一定要写注释!一定要写注释! 重要的事情说三遍!   1.首先,准备工作:   1)引用:            获取途径:VS里的扩展和更新、NuGet等。   2)数据库模型:...

MySQL 空事务

    问题描述;    研发同事反应MySQL数据库有锁,检查innodb_trx时,发现有很多长时间未结束的空事务。    这些事务的trx_mysql_thread_id都为0,因此不能通过kill   id 的方式强制关闭这些长时间未结束的僵尸事务。             SELECT        trx_mysql_thread_id, tr...

db2 sqlcode

DB2错误信息(按sqlcode排序)  sqlcode sqlstate 说明  000 00000 SQL语句成功完成  01xxx SQL语句成功完成,但是有警告  +012 01545 未限定的列名被解释为一个有相互关系的引用  +098 01568 动态SQL语句用分号结束  +100 02000 没有找到满足SQL语句的行  +110 0156...