参考:
oracle手动锁定表 百度
oracle一个事务期间 锁定一个表 百度
oracle事务控制 百度
标签: it |
分类: 工作 |
整天说Oracle的事务实际上是指INSERT,UPDATRE,DELETE,SELECT...FOR UPDATE语句,即DML语句
当在应用程序中执行第一条SQL语句时,开始事务;当执行COMMIT或ROLLBACK语句时,结束事务。
1.事务和锁
当执行事务操作(DML语句)时,Oracle会被作用表上加表锁,以防止其他用户改变表结构;同时会在被作用行上加行锁,以防止其他事务在相应行上执行DML操作。
会话A:
UPDATE emp SET sal=sal*2 WHERE ename='Tom';
会话B:
ALTER TABLE emp ADD remark VARCHAR2(100);
ERROR 位于第1行;
ORA-00054:资源正忙,需求指定NOWAIT
为了确保数据库数据的读一致性,不允许其他用户读取脏数据(未提交数据)。
假定会话A将雇员SCOTT工资修改为2000(未提交),那么其他会话将只能查询到原来的工资。只有在会话A提交了实务之后,其他会话才能查询到新工资。
会话A:
UPDATE emp SET sal=2000
WHERE ename='Tom';
会话B:
SELECT sal FROM emp WHERE ename='Tom';
SAL
--------
3000
2.提交事务
使用COMMIT语句可以提交事务。当执行了COMMIT语句之后,会确认事务变化,结束事务,删除保存点,释放锁。当使用COMMIT语句结束事务之后,其他会话将可以查看到事务变化后的新数据。
会话A:
UPDATE emp SET sal=2000
WHERE ename='Tom';
COMMIT;
会话B:
SELECT sal FROM emp WHERE ename='Tom';
SAL
------
2000
3.回退事务
保存点(savepoint)是事务中的一点,用于取消部分事务。当结束事务时,会自动删除该事务所定义的所有保存点。在执行ROLLBACK命令时,通过指定保存点可以取消部分事务。
☆设置保存点
sacepoint a;
或
exec dbms_transaction.savepoint('a');
☆取消部分事务
rollback to a;
或
exec dbms_transaction.rollback_savepoint('a');
☆取消全部事务
rollback;
或
exec dbms_transaction.rollback;
4.只读事务
不会取得新的数据变化,从而确保取得特定时间点的数据信息。
会话A:
SET TRANSACTION READ ONLY;①
SELECT sal FROM emp WHERE ename='Tom';③
会话B:
UPDATE emp SET sal=1000②
WHERE ename='Tom';
COMMIT;
SAL
------
2000
5.顺序事务
上面的只读事务可以使用用户取得特定时间点的数据信息,当设置了只读事务时,会话将不能执行DML语句,为了使用户可以取得特定时间点的数据,并且允许执行DML操作,可以使用顺序事务。
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
oracle锁定表 百度
SELECT /*+ rule */ s.username,
decode(l.type,'TM','TABLE LOCK',
'TX','ROW LOCK',
NULL) LOCK_LEVEL,
o.owner,o.object_name,o.object_type,
s.sid,s.serial#,s.terminal,s.machine,s.program,s.osuser
FROM v$session s,v$lock l,dba_objects o
WHERE l.sid = s.sid
AND l.id1 = o.object_id(+)
AND s.username is NOT Null
--kill session语句
alter system kill session'50,492';
--以下几个为相关表
SELECT * FROM v$lock;
SELECT * FROM v$sqlarea;
SELECT * FROM v$session;
SELECT * FROM v$process ;
SELECT * FROM v$locked_object;
SELECT * FROM all_objects;
SELECT * FROM v$session_wait;
--1.查出锁定object的session的信息以及被锁定的object名
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# ;
--2.查出锁定表的session的sid, serial#,os_user_name, machine name, terminal和执行的语句
--比上面那段多出sql_text和action
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#;
--3.查出锁定表的sid, serial#,os_user_name, machine_name, terminal,锁的type,mode
SELECT s.sid, s.serial#, s.username, s.schemaname, s.osuser, s.process, s.machine,
s.terminal, s.logon_time, l.type
FROM v$session s, v$lock l
WHERE s.sid = l.sid
AND s.username IS NOT NULL
ORDER BY sid;
这个语句将查找到数据库中所有的DML语句产生的锁,还可以发现,
任何DML语句其实产生了两个锁,一个是表锁,一个是行锁。
杀锁命令
alter system kill session 'sid,serial#'
SELECT /*+ rule */ s.username,
decode(l.type,'TM','TABLE LOCK',
'TX','ROW LOCK',
NULL) LOCK_LEVEL,
o.owner,o.object_name,o.object_type,
s.sid,s.serial#,s.terminal,s.machine,s.program,s.osuser
FROM v$session s,v$lock l,dba_objects o
WHERE l.sid = s.sid
AND l.id1 = o.object_id(+)
AND s.username is NOT NULL
如果发生了锁等待,我们可能更想知道是谁锁了表而引起谁的等待
以下的语句可以查询到谁锁了表,而谁在等待。
以上查询结果是一个树状结构,如果有子节点,则表示有等待发生。
如果想知道锁用了哪个回滚段,还可以关联到V$rollname,其中xidusn就是回滚段的USN
col user_name format a10
col owner format a10
col object_name format a10
col object_type format a10
SELECT /*+ rule */ lpad(' ',decode(l.xidusn ,0,3,0))||l.oracle_username User_name,
o.owner,o.object_name,o.object_type,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
ORDER BY o.object_id,xidusn DESC