锁(lock)是一种防止多个事务访问同一资源时产生破坏性的相互影响的机制。通常,高并发数据库需要利用锁机制解决数据并发访问、一致性及完整性问题。

  前面提到的资源(resource)大致可以分为两类:

  ● 用户对象:例如表及数据行

  ● 对用户透明的系统对象:例如内存中的共享数据结构、数据字典中的信息

  任何 SQL 语句执行时 Oracle 都隐式地对 SQL 所需的锁进行管理,因此用户无需显式地对资源加锁。Oracle 默认采用的锁机制能尽可能地减小对数据访问的限制,在保证数据一致性的同时实现高度的数据并发性。Oracle也支持用户手工加锁的操作。

  锁的类型

  分法很多,在此列二:

  按数据类型分

  ① 保护元数据 --->TM锁(表级锁)

  表级锁有5个,重要的有2个:lmode  type  (v$lock查询)

        3      RX

        6       X

  ② 保护数据 --->TX锁(事务锁)

  一个事务对应一个事务锁(TX),并且其是因为行级锁(X)产生的。有行级锁有事务锁。所以一个事务开始至少会有3个锁:TX、X、RX

  按作用类型分

  ① 保护chain --->lock

  ② 保护buffer --->latch

  锁的模式

  在高并发环境,oracle采取两种模式的锁:

  (一)X模式(排他锁模式):对数据进行修改时必须获得此种模式的锁。第一个排他地对资源加锁的事物是可以对此资源进行修改的事物,直至排他锁被释放。

  (二)S模式(共享锁模式):对数据进行读取的多个用户可共享此数据,这些用户可以对资源加以共享锁,防止其他用户并发地修改此资源(对数据进行修改的用户需要排他锁)。多个事务可以对相同的资源加共享锁。

  锁的持续时间

  事务内各语句获得的锁在事务执行期内有效,以防止事务间破坏性的相互干扰。如果某个事务中的 SQL 语句对数据进行了修改,只有在此事务提交后开始的事务才能看到前者修改的结果。当用户commit或者rollback一个事务时,Oracle 将释放此事务内各个 SQL 语句获得的锁。当用户在事务内回滚到某个保存点(savepoint)后,Oracle 也会释放此保存点后获得的锁。等待事务不会对可用资源加锁而是继续等待,直至拥有其所等待资源的事务完成提交或回滚。

  锁转换及锁升级

  对于数据行来说,RX已经是限制程度高的锁,因此无需再进行锁转换(lock conversion)。

  对于数据表,Oracle 能够自动地将限制程度较低的锁转化为限制程度更高的锁。例如,某个事务内使用了SELECT ... FOR UPDATE 语句对数据行加锁。此时,事务获得了相关数据行上的行级锁X,及相关数据表上的RS。如果此事务将对某些数据行进行更新,那么之前获得的RS将自动地转换为RX。

  锁升级(lock escalation)是指处于低粒度级别(例如,数据行级)上的锁被数据库升级为更高粒度级别(例如,表)上的锁。例如,某个用户已经对某个表内的多行数据加锁,某些数据库管理系统会将用户的这些行级锁升级为一个单一的表级锁。此时系统内锁的数量减少了,对被锁资源的限制程度增加了。Oracle 数据库中不存在锁升级。锁升级将显著地增加发生死锁(deadlock)的可能性。例如,数据库试图将事务 T1 中对某资源的锁升级,同时事务 T2 也拥有此资源的锁。如果此时事务 T2 也需要将锁升级则将产生死锁。