Oracle 数据库会为事务自动锁定资源,以防止其他事务进行某些需要独占访问同一资源的操作。数据库在不同的限制级别自动获取不同类型的锁,这依赖于不同的资源和正在执行的操作。
注意:
执行简单读取时,数据库绝不会锁定行。
Oracle 数据库锁分为以下几类。
DML锁
DML 锁,也称为数据锁,确保由多个用户并发访问的数据的完整性。例如, DML 锁可防止两个客户从一个在线书店购买某一本书所剩的最后一个拷贝。DML 锁也可以防止多个相互冲突的 DML 或 DDL 操作产生破坏性干扰。
DML 语句自动获取下列类型的锁:
行锁 (TX)
表锁 (TM)
在下面几节,在每种类型的锁或锁模式后的括号中,首字母缩写词是用于在Oracle 企业管理器 (企业管理器)的锁监视器中的缩写。企业管理器中可能将任何的表锁显示为TM,而不显示表锁的模式(如RS或SRX)。
行锁(TX)
行锁,也称为 TX锁,是一个表中单个行上的锁。一个事务在被INSERT、 UPDATE、DELETE、MERGE、或 SELECT … FOR UPDATE等语句所修改的每一行上获取一个行锁。行锁一直存在直到事务提交或回滚。
行锁主要作为一种排队的机制,以防止两个事务修改相同的行。数据库始终以独占模式锁定修改的行,以便其他事务不能修改该行,直到持有锁的事务提交或回滚。行锁定提供了近乎最细粒度的锁定,并因此提供了近乎最佳的并发性和吞吐量。
注意:
如果一个事务因为数据库实例失效而终止,会先进行块级恢复以使行可用,之后进行整个事务恢复。
如果一个事务在某行上获取了一个锁,则该事务也将在包含该行的表上获取一个锁。表锁可防止冲突性的DDL 操作在当前事务中会覆盖数据更改。图 9-2 演示了在一个表中第三行上的更新。Oracle 数据库将自动在更新行上置一个独占锁,且在表上置一个次独占锁。
行锁和并发
表 9-6 说明了Oracle数据库如何在并发事务中使用行锁。3个会话同时查询相同的行。会话2 和会话 3 对不同的行进行未提交更新,而会话3没有做任何更新。每个会话可以看到自己的未提交更新,但看不到其他会话中所做的任何未提交更新。
行锁存储
与某些数据库使用锁管理器在内存中维护一个锁列表不同,Oracle数据库将锁信息存储在包含锁定行的数据块中。
数据库使用排队机制来获取行锁。如果事务需要为某个未锁定的行获取一个锁,则事务将在数据块上置一个锁。被此事务修改的每个行指向存储在块头中的事务 ID 的一个副本。
当事务结束时,事务 ID 仍然保留在块头中。如果一个不同的事务想要修改某行,则它使用该事务 ID 来确定锁是否处于活动状态。如果锁是活动的,则会话要求该锁被释放时得到通知。否则,事务获取该锁。