1、共享方式的表封锁
共享方式的表封锁是对表中的所有数据进行封锁,该锁用于保护查询数据的一致性,防止其它用户对已封锁的表进行更新。其它用户只能对该表再施加共享方式的锁,而不能再对该表施加独占方式的封锁,共享更新锁可以再施加,但不允许持有共享更新封锁的进程做更新。共享该表的所有用户只能查询表中的数据,但不能更新。共享方式的表封锁只能由用户用SQL语句来设置,基语句格式如下:
LOCK TABLE <表名>[,<表名>]...
IN SHARE MODE [NOWAIT]
执行该语句,对一个或多个表施加共享方式的表封锁。当指定了选择项NOWAIT,若该封锁暂时不能施加成功,则返回并由用户决定是进行等待,还是先去执行别的语句。持有共享锁的事务,在出现如下之一的条件时,便释放其共享锁:
A、执行COMMIT或ROLLBACK语句。
B、退出数据库(LOG OFF)。
C、程序停止运行。
共享方式表封锁常用于一致性查询过程,即在查询数据期间表中的数据不发生改变。
2、独占方式表封锁
独占方式表封锁是用于封锁表中的所有数据,拥有该独占方式表封锁的用户,即可以查询该表,又可以更新该表,其它的用户不能再对该表施加任何封锁(包括共享、独占或共享更新封锁)。其它用户虽然不能更新该表,但可以查询该表。独占方式的表封锁可通过如下的SQL语句来显示地获得:
LOCK TABLE <表名>[,<表名>]....
IN EXCLUSIVE MODE [NOWAIT]
独占方式的表封锁也可以在用户执行DML语句INSERT、UPDATE、DELETE时隐含获得。拥有独占方式表封锁的事务,在出现如下条件之一时,便释放该封锁:
(1)、执行COMMIT或ROLLBACK语句。
(2)、退出数据库(LOG OFF)
(3)、程序停止运行。
独占方式封锁通常用于更新数据,当某个更新事务涉及多个表时,可减少发生死锁。================================================================================上面说到共享方式和独占方式,我的理解如下:1、两种方式都能够保证加锁期间只能由锁的施加者更新
2、加锁期间别的用户都可以进行查询这样看来,这两种方式好像没有什么大的区别呀,还请明白人讲解一下(*^__^*)
共享方式的表封锁是对表中的所有数据进行封锁,该锁用于保护查询数据的一致性,防止其它用户对已封锁的表进行更新。其它用户只能对该表再施加共享方式的锁,而不能再对该表施加独占方式的封锁,共享更新锁可以再施加,但不允许持有共享更新封锁的进程做更新。共享该表的所有用户只能查询表中的数据,但不能更新。共享方式的表封锁只能由用户用SQL语句来设置,基语句格式如下:
LOCK TABLE <表名>[,<表名>]...
IN SHARE MODE [NOWAIT]
执行该语句,对一个或多个表施加共享方式的表封锁。当指定了选择项NOWAIT,若该封锁暂时不能施加成功,则返回并由用户决定是进行等待,还是先去执行别的语句。持有共享锁的事务,在出现如下之一的条件时,便释放其共享锁:
A、执行COMMIT或ROLLBACK语句。
B、退出数据库(LOG OFF)。
C、程序停止运行。
共享方式表封锁常用于一致性查询过程,即在查询数据期间表中的数据不发生改变。
2、独占方式表封锁
独占方式表封锁是用于封锁表中的所有数据,拥有该独占方式表封锁的用户,即可以查询该表,又可以更新该表,其它的用户不能再对该表施加任何封锁(包括共享、独占或共享更新封锁)。其它用户虽然不能更新该表,但可以查询该表。独占方式的表封锁可通过如下的SQL语句来显示地获得:
LOCK TABLE <表名>[,<表名>]....
IN EXCLUSIVE MODE [NOWAIT]
独占方式的表封锁也可以在用户执行DML语句INSERT、UPDATE、DELETE时隐含获得。拥有独占方式表封锁的事务,在出现如下条件之一时,便释放该封锁:
(1)、执行COMMIT或ROLLBACK语句。
(2)、退出数据库(LOG OFF)
(3)、程序停止运行。
独占方式封锁通常用于更新数据,当某个更新事务涉及多个表时,可减少发生死锁。================================================================================上面说到共享方式和独占方式,我的理解如下:1、两种方式都能够保证加锁期间只能由锁的施加者更新
2、加锁期间别的用户都可以进行查询这样看来,这两种方式好像没有什么大的区别呀,还请明白人讲解一下(*^__^*)
ORA-06512: 在"DJB.MYPROC", line 14
ORA-06512: 在"DJB.TRIGGER_TEST1", line 4
ORA-04088: 触发器 'DJB.TRIGGER_TEST1' 执行过程中出错-------------------------请看下面的触发器-------------------------------create or replace trigger trigger_test1
before insert on test1
for each row
declare
maxid number(3);
counter number(3);
vid number(3);
cursor cCycleType is select insertid from test1 order by insertid asc;
pragma autonomous_transaction;
needid number(3);
begin
select count(*) into maxid from test1;
if maxid = 0 then
maxid := 1;
else
select max(insertid) into maxid from test1;
if maxid > 10 then
lock table test1 in EXCLUSIVE mode;
counter := 1;
open cCycleType;
loop
fetch cCycleType into vid;
exit when cCycleType%notfound;
update test1 set insertid = counter where insertid = vid;
counter := counter +1 ;
dbms_output.put_line(counter);
end loop;
CLOSE cCycleType;
commit;
end if;
end if;
select count(*) into needid from test1;
if needid >= 1 then
select max(insertid) into needid from test1;
dbms_output.put_line(needid);
:new.insertid := needid+1;
else
:new.insertid := 1;
end if;
end trigger_test1;
锁模式 锁描述 解释 SQL操作
0 none
1 NULL 空 Select
2 SS(Row-S) 行级共享锁,其他对象只能查询这些数据行 Select for update、Lock for update、Lock row share
3 SX(Row-X) 行级排它锁,在提交前不允许做DML操作 Insert、Update、Delete、Lock row share
4 S(Share) 共享锁 Create index、Lock share
5 SSX(S/Row-X) 共享行级排它锁 Lock share row exclusive
6 X(Exclusive) 排它锁 Alter table、Drop able、Drop index、Truncate table 、Lock exclusive
表2 数据字典视图说明
视图名 描述 主要字段说明
v$session 查询会话的信息和锁的信息。 sid,serial#:表示会话信息。program:表示会话的应用程序信息。row_wait_obj#:表示等待的对象。和dba_objects中的object_id相对应。
v$session_wait 查询等待的会话信息。 sid:表示持有锁的会话信息。Seconds_in_wait:表示等待持续的时间信息Event:表示会话等待的事件。
v$lock 列出系统中的所有的锁。 Sid:表示持有锁的会话信息。Type:表示锁的类型。值包括TM和TX等。ID1:表示锁的对象标识。lmode,request:表示会话等待的锁模式的信息。用数字0-6表示,和表1相对应。
dba_locks 对v$lock的格式化视图。 Session_id:和v$lock中的Sid对应。Lock_type:和v$lock中的type对应。Lock_ID1: 和v$lock中的ID1对应。Mode_held,mode_requested:和v$lock中的lmode,request相对应。
v$locked_object 只包含DML的锁信息,包括回滚段和会话信息。 Xidusn,xidslot,xidsqn:表示回滚段信息。和v$transaction相关联。Object_id:表示被锁对象标识。Session_id:表示持有锁的会话信息。Locked_mode:表示会话等待的锁模式的信息,和v$lock中的lmode一致。col owner for a12
col object_name for a16
select b.owner,b.object_name,l.session_id,l.locked_mode
from v$locked_object l, dba_objects b
where b.object_id=l.object_id; select t2.username,t2.sid,t2.serial#,t2.logon_time
from v$locked_object t1,v$session t2
where t1.session_id=t2.sid order by t2.logon_time;
如果有长期出现的一列,可能是没有释放的锁。我们可以用下面SQL语句杀掉长期没有释放非正常的锁:
alter system kill session 'sid,serial#';
如果出现了锁的问题, 某个DML操作可能等待很久没有反应。
当你采用的是直接连接数据库的方式,也不要用OS系统命令 $kill process_num 或者 $kill -9 process_num来终止用户连接,因为一个用户进程可能产生一个以上的锁, 杀OS进程并不能彻底清除锁的问题。