官方文档:http://docs.oracle.com/cd/E11882_01/server.112/e40540/consist.htm#CNCPT221
1. 什么是数据并发和数据一致(Data concurrency and consistency)
data concurrency : 保证所有用户可以在同时访问数据
data consistency : 保证用户看到的数据是一致的,包括自己修改的数据和别的用户修改的已提交数据。
2. 多版本读一致性(multiversion read consistency)
2.1 语句级别的读一致性
当事务隔离级别为:read committed 返回select语句刚刚触发时的数据,如果select开始于SCN 1000,则select返回的数据和SCN 1000保持一致
当事务隔离级别为:serializable,read only 返回事务开始时的数据,如果一个事务开始于SCN 1000,则该事务中所有的select语句返回的数据都和SCN 1000保持一致,除非事务内对数据进行更改。
闪回查询(select .. as of) 返回闪回查询指定时间或者scn的数据
2.2 读一致和回滚段(undo segment)
当用户修改数据时,oracle会将修改的数据写入回滚段,回滚段中会包含被用户修改且未提交的数据以及最近提交的数据,查询时,可以通过查询某一时间点的数据快照来提供读一致性。
当事务隔离级别为read committed,oracle是按照如下方式通过回滚段保证读一致性的:
假设查询开始于SCN 10023,查询只会返回在SCN 10023已经commit的数据,在SCN 10024有两个数据块发生了变更但是对于SCN 10023并不可见,所以oracle会生成两个consistency read(CR) clones克隆SCN 10006和10021的数据,重新组织数据后返回,oracle通过这种方式来组织脏读(dirty reads)。
2.3 ITL(INTERESTED TRANSACTION LIST)事务槽
每个数据块的头部都有一个专门用来记录事务信息的区域。
3. ANSI/ISO事务隔离级别
脏读:一个事务读取另一个事务已经修改但为commit的数据
不可重复读:在A事务里,执行select语句得到返回结果,此时B事务修改了之前select得到的数据,再次执行select得到B事务修改后的数据
幻想读:在A事务里,先执行select语句得到返回结果,此时B事务插入了满足之前select条件的数据,再次执行select得到B事务插入的数据
SQL标准定义四个级别的事务隔离级别,oracle只支持其中的read committed(默认)和serializable,另外数据还提供了read-only模式
Isolation Level | Dirty Read | Nonrepeatable Read | Phantom Read |
---|---|---|---|
Read uncommitted |
Possible |
Possible |
Possible |
Read committed |
Not possible |
Possible |
Possible |
Repeatable read |
Not possible |
Not possible |
Possible |
Serializable |
Not possible |
Not possible |
Not possible |
4. oracle的事务隔离级别
设置事务隔离级别:set transaction isolation level read committed | serializable;
设置事务只读模式:set transaction read only;
4.1 read committed
select返回的是查询开始时的数据,而不是事务开始时的数据。
假设事务A中,对一个百万量级的表tb开始全表扫描,扫描的过程中,事务B对表的某行数据做了修改,当前扫描返回的还是事务B修改之前的数据。扫描结束后,再次执行select,返回的是事务B修改的数据。所以多次执行select可能会引发不可重复读和幻想读。
4.2 serializable
select返回的是事务开始时的数据,给人的感觉是没人其他用户在修改数据。不会出现脏读,不可重复读和幻想读。
当事务隔离级别为serializable的事务试图修改事务开始后其他事务修改并commit的数据时,会报错 ora-08177。
4.3 read only模式
当事务被设置为read only后只有sys用户可以修改数据,适用于比较耗时的复杂报表的生成。
5. oracle锁机制
数据库通常会提供两种类型的锁:排他锁(exclusive locks)和共享锁(share locks)
oracle数据库中读(reader)和写(writer)的关系如下:
① A row is locked only when modified by a writer. 当数据被修改的时候会被锁住。
② A writer of a row blocks a concurrent writer of the same row. 同一时间 只能有一个写进程在修改数据。
③ A reader never blocks a writer.
④ A writer never blocks a reader.
oracle会在数据块中保存锁的相关信息,采用队列机制来获取锁。当一个事务A获得一个未锁定行的lock时,会在数据库中放一个lock,事务A改变的每一行数据都会在块头存储该事务行的事务ID。当事务A结束后,事务ID依然保留在块头。当事务B想要获得lock时,会检查块头的事务ID对应的事务是否是active状态,如果不是则获取lock。
5.1 DML locks 保护数据
Row locks(TX) : 当事务对一行数据进行INSERT,UPDATE,DELETE,MERGE或者select ..for update时会获得TX锁。
Table locks(TM) : 当事务对表进行INSERT,UPDATE,DELETE,MERGE,SELECT FOR UPDATE或者lock table时会获得TM锁。
TM锁会有如下几种模式:
① Row share(RS) or subshare table lock (SS) 事务获得表的SS并准备更新表的数据
② Row exclusive table lock (RX) or subexclusive table lock (SX) 持有SX的事务允许其他事务对表的行进行插入,更新,删除,或者lock.同一时间点,在一个table上可以有多个RX和SS。
③ Share table lock (S) :同一时间点,在一个table上可能有多个S。持有S的事务允许其他事务对表进行查询,也允许其他持有S的事务对表进行数据更新。因为同一时间可能有多个事务获得某个表的S,所以仅仅获得表的S不代表可以对表进行数据更新。
④ Share row exclusive table lock (SRX) or share_subexclusive table lock (SSX) : 同一时间点,在一个table上只能有一个SSX。假设事务A获取了表tb的SSX,则其他事务只能对表tb进行查询操作。
⑤ Exclusive table lick (X) : 禁止其他事务对表施加任何类型的DML操作或者放置任何类型的锁。
5.2 DDL locks (Data dictionary locks)
oracle数据库从来不会锁定整个数据字典,我们也不能显示的获取DDL锁。
当创建存储过程时,oracle会自动获取出现在存储过程中的所有数据库对象的DDL锁,在存储过程编译完成之前,这些DDL锁不允许任何对这些数据库结构的改变或者drop。
排他DDL锁(Exclusive DDL Locks):例如drop table 的同时不能对这个table添加注释,反之亦然。
共享DDL锁(Share DDL Locks):例如当create procedure会获取数据库对象的共享DDL锁,其他的create procedure也可以同时获得这些数据库对象的共享DDL锁。持有数据库对象共享DDL锁的事务可以保证引用的数据库对象的定义和结构是保持不变的。
breakable parse locks (parse block).
5.3 system locks 如latch mutex
latch: 用于保护内存资源. 假设后台进程A(DBWn,LGWR等)需要从shared pool分配内存,后台进程A需要首先获取shared pool latch以阻止别的进程同时分配内存资源。假设A内存分配结束后,后台进程B由于SQL解析需要获取library cache latch,并不会影响shared pool的其他区域。
和队列不同,后台进程不会排队等待获取latch,假设后台进程A获取了latch,没有释放,后台B会不停的循环去获取latch,直到A释放latch。当一个后台进程不停地尝试获取latch是会发生latch spinning,当一个进程在重新申请latch之前已经释放掉了CPU就会发生latch sleeping。
mutex(manual exclusion object): mutex和latch比较相似,latch是保护一组数据库对象,mutex是保护一个数据库对象。,mutex占用较少的内存。
internal locks: Dictionary cache locks,File and log management locks,Tablespace and undo segment locks