并发控制(concurrency control)是数据库提供的函数集合,允许多个人同时访问和修改数据。
锁(lock)是Oracle管理共享数据库资源并发访问并防止并发数据库事务之间“相互干涉”的核心机制之一。
Oracle使用了多种锁,包括如下几种类型。
- TX(事务处理锁):修改数据的事务在执行期间会获得这种锁。
- TM(DML队列)锁和DDL锁:在你修改一个对象的内容(对应TM锁)或对象本身(对应DDL锁)时,这些锁可以确保对象的结构不被修改。
- 闩(latch)和Mutex: Oracle的内部锁,用来协调对其共享数据结构的访问。
不论是哪一种锁,请求锁时都存在最小开销。TX事务锁在性能和基数方面可扩展性极好。TM锁和DDL锁要尽可能地采用限制最小的模式。闩和队列锁(enqueue)都是轻量级的,而且都很快。如果应用设计不当,锁定的时间过长,而导致数据库出现阻塞,就会带来问题。如果能很好地设计代码,利用Oracle的锁定机制就能建立可扩展的、高度并发的应用。
Oracle 的读一致性多版本模型应用于语句级(statement level),即应用于每一个查询。
还应用于事务级(transaction level)。
数据库中事务的基本作用是将数据库从一种一致状态转变为另一种一致状态。ISO SQL标准指定了多种事务隔离级别(transaction isolation level).
事务隔离级别
- 脏读(dirty read)(读取未提交的数据)
- 不可重复读(nonrepeatable read)
- 幻像读(phantorn read)(与不可重复读的区别在于: 幻读已经读取的数据不会改变,与之前相比,会有更多的数据满足查询条件)
Read Uncommitted
Read UNCOMMITTED 隔离级别允许脏读。
Read UNCOMMITTED 隔离级别根本目标是提供一个基于标准的定义支持非阻塞读。
Read COMMITTED
Read COMMITTED隔离级别是指: 事务只能读取数据库已经提交的数据。这里没有脏读。可能有不可重复读(即,在同一个事务中重新读取同一行可能返回不同的答案)和幻像读(与事务早期相比,查询不光能看到已经提交的行,还可以看到新插入的行。)
REPEATABLE READ
REPEATABLE READ 的目标是提供这样一个隔离级别,它不仅能给出一致的正确答案,还能避免丢失更新。
1.得到一致的答案
给定查询得到的结果相对于某个时间点来说应该是一致的。大多数数据库(不包括Oracle)都是通过使用低级共享读锁来实现可重复读。共享读锁会防止其他会话修改我们已经读取的数据。这会降低并发性。Oracle则采用了更具并发性的多版本模型来提供读一致的答案。
Oracle中可以得到语句级的读一致性,而不会带来读阻塞写的现象,也不会导致死锁。Oracle从不使用共享读锁,永远不会。Oracle选择了多版本控制机制,尽管更难实现,但绝对更具并发性。
2.丢失更新:另一个可移植性问题
在采用共享读锁的数据库中,REPEATABLE READ 的一个常见用途是防止丢失更新。
如果是读取数据时在所有数据上都加共享读锁,会严重限制并发读和修改。
SERIALIZABLE
最受限的隔离级别,提供了最高程度的隔离性。
只要保证以下几点就能很有成效:
- 一般没有其他人修改相同的数据
- 需要事务级读一致性
- 事务都很短
READ ONLY
READ ONLY事务与SERIALIZABLE事务很相似,唯一的区别是READ ONLY事务不允许修改。
一致性读和当前读
Oracle处理修改语句时会完成两类块获取。它会获取以下两步“
一致读(consistent read)
当前读(current read)