必须具备以下四个属性 ACID属性:
有事务必有锁和undo
2.1事务采用隐性方式,起始于session的第一条DML语句
2.2事务结束于:
注:在一个事务中,若是某dml语句失败,之前任何dml语句将保持完好,且不会提交
一个session只有一个事务,它可以在一个事务结束后产生第二个事务,但是不会同时存在2个事务
savepoint功能允许事务进行中设置一个标记(保存点),这个标记可控制rollback的效果,即在一个事务中回滚掉最近的部分dml语句,保留下保存点之前的dml语句,并使事物本身继续执行。即回滚到保存点这个操作并不使事务结束。
savepoint sp1;
delete from emp1 where empno=7900;
savepoint sp2;
update emp1 set ename='timran' where empno=7788;
select * from emp1;
rollback to sp2;
select * from emp1;
rollback to sp1;
//rollback to XXXX不会使事务结束,只有rollback可以使事务结束
此时去sys下检查
SQL> select count(*) from v$transaction;
COUNT(*)
----------
1
表明事务还可以继续操作
scn全称:system change number
它是一个不断增长的整数,相当于oracle内部的一个时钟,只要数据库有变更,这个scn就会+1,oracle通过scn记录数据库事务的一致性。scn涉及实例恢复和介质恢复的核心概念。控制文件、数据文件,日志文件都有scn,block上也有scn
实现一致性:背后是物理层面的block读,oracke会依据select命令,记录此刻的scn值,然后以scn值同所读的每个block上的scn作比较,若读到的快上的scn大于select发出时记录的scn,则需要利用undo段,在内存中构造CR块。
得到当前scn的方法:
sys:select current_scn from v$database;
select dbms_flashback.get_system_change_number from dual;
有事务才有锁的概念(对事务上锁?)。oracle锁分类如下:
DML锁(data locks,数据锁),用于保护数据完整性
DDL锁(dictionary locks ,数据字典所),用于保护数据库对象的结构,如表、索引等的结构定义,做drop alter时上锁
system锁(internal locks and latches(内存中)),保护数据库的内部结构
注:
数据锁/dml锁:TM锁 TX锁
例:一个update语句,有表级锁(tm)和行锁(tx),oracle先申请表级锁tm(其中的rx锁),后系统再自动申请行锁(tx),并将实际锁定的数据行的锁标定位置(即指向其中的tx锁)
对dml操作
tx行锁只有一种
tm表锁有5中,分别rs 2,rx 3,s 4。srx 5,x 6。
row share 行共享(rs),允许其他用户同时更新其他行,允许其他用户同时增加共享锁,不允许独占(排他性质)的锁
row exclusive 行排他(rx),允许其他用户同时更新其他行,只允许其他用户同时加行共享锁或者行排他锁
share共享(s),不允许其他用户同时更新任何其他行,只允许用户同时加共享锁胡总和行共享锁
share row exclusive(srx)共享排他行、,不允许其他用户同时更新其他行,只允许其他行用户同时加共享锁
exclusive (x)排他,其他用户禁止更新任何行,禁止用户同时加任何排他锁
sql语句 |
加锁模式 | 许可其他用户加锁模式 |
select * from table_name | 无 | rs,rx,s,srx,x |
insert,update,delete (dml操作) |
rx | rs,rx |
select * from table_name for update | rx | rs,rx |
lock table table_name in row share mode | rs | rs,rx,x,srx |
lock table table_name in row exclusive mode | rs | |
lock table table_name in share mode | ||
lock table table_name in share row exclusive mode | ||
lock table table_name in exclusive mode |
做dml操作时,如insert,update,delete,以及select 。。。for update由oracle自动完成加锁
select * 不产生事务,但是select * ... for update会产生事务,因为有事务才有锁,而此语句有锁。
执行:
select * from emp where deptno=10 for update; //会产生锁将select * from emp where deptno=10 得结果锁住,便于后续操作。
若是另外一个session再次执行select * from emp where job='clerk';该会话会被停掉不走;
此时可在select * from emp where job='clerk'添加以下三种参数:
若有4条clerk记录被锁住,而执行者不在,管理员只能做如下操作:
而kill session动作是rollback,而非commit;ddl操作是commit,因为commit命令被ddl嵌入了
lock table table_name in share mode
观察锁的静态和动态视图:
select * from v$lock;
select * from dba_locks where session_id=149;
session1:
update ... id=2000 where id=2;
session 2:
update ... id=1000 where id=1;
session1:
update ... id=1000 where id=1; //此时session被锁住
session 2:
update ... id=1000 where id=1; //此时形成死锁,oracle会检测到结果并自动弹开,此时若是结束session 2 得事务,session1 得内容会得以继续
定位
select * from v$lock where type in ('TM','TX');
select a.sid,a.serial#,b.sql_text from v$session a,v$sql b where a.prev_sql_id=b.sql_id and a.sid=127;
select sid,serial#,blocking_session,username,event from v$session where blocking_session_status='VALID'; //或者根据v$lock视图的block和request确定session阻塞关系,确定无误后再杀掉这个session
更多视图:v$session,v$process,v$sql,v$locked,v$sqlarea等等