oracle使用两种类型的锁
1排他锁模式阻止相关资源被共享。这个锁模式被获取来修改数据。第一个事务排他的来锁定资源以便来修改资源。
2共享锁可以让资源共享,依赖相关的操作。多个用户读取数据可以共享数据,持有共享锁来阻止写入者并发访问(需要排他锁),一些事务可以再同一个资源上同时获取共享锁。
数据锁转换versus锁扩大
一个事务对所有插入的行,更新的行和删除的行持有排他锁,因为行锁在限制最高级获得的,所以没有行转换。oracle会自动适当的转换表锁到一个更高限制的锁,比如:假如一个事务使用select语句带有for update来锁住行,结果,它获取排他行锁和共享表锁,如果事务在后面更新了很多行,共享表锁自动的转换成行排他锁。
锁扩大发生在很多的锁在同一粒度被持有(如,行)数据库升级锁到更高的粒度,例如;如果一个用户锁住了一个表的很多行,数据库自动扩大用户的行锁到一个用户表。锁的数量减少了,但是被锁的限制增加了。
oracle从不扩大锁,锁扩大增大了死锁的风险。想象下面的情况,事务t1想要扩大锁,但是t2正持有锁,如果t2也要求相同数据锁升级,那么死锁发生了。
死锁检查,orcale自动检测死锁,并回滚其中的一个事务,抛出相应的错误,被回滚的语句是检测到死锁的语句。
oracle的锁类型
Lock | Description |
---|---|
DML locks (data locks) | DML locks protect data. For example, table locks lock entire tables, row locks lock selected rows. |
DDL locks (dictionary locks) | DDL locks protect the structure of schema objects—for example, the definitions of tables and views. |
Internal locks and latches | Internal locks and latches protect internal database structures such as datafiles. Internal locks and latches are entirely automatic. |
dml锁
dml锁是确保在多用户同时访问数据的的时候维护数据的一致性。dml锁自动获取表级和行级锁。
行锁(TX)
行锁主要用来放置2个事务同时修改同一行。当一个事务需要修改一行,需要一个行锁。对一个事务没有行锁数量的限制,oracle不扩大锁到更粗的粒度。行锁提供细粒度的锁,有助于并行和吞吐量。多版本并发控制和行级锁结合意味着用户竞争着访问同一行:
1读不用等写
2写不用等读,除非使用select ..for update。
3写不等待写,除非他们是更新相同的行。
一个事务在下面的几个操作中需要对修改的行有排它锁:insert update delete 与select ..for update
如果一个事务对行获取了行锁,事务也会要求相应表的表锁,表锁阻止了可能会覆盖数据改变的ddl操作。
表锁(TM)
表锁主要用来对并发ddl操作的并发控制。比如在dml操作期间,阻止表被删除。当ddl或是dml语句在表上的时候,需要表锁。表锁不影响dml的并发操作,对分区表,表锁在表与子分区上都要获取。
在下面的语句中需要表锁:insert,update,delete,select...for update 与lock table。这些dml操作要求表锁有2个目的:保持dml对表的访问,阻止可能与事务冲突的ddl操作,任何的表锁阻止获取排他ddl锁在相同的表上,因此阻止了ddl操作。
表锁能在任意的几个模式中被持有:row share(rs),row exclusize(rx),share(s),share row exclusize(srx) exclusive(x).
下面是语句获取表锁的情况
Table 13-3 Summary of Table Locks
SQL Statement | Mode of Table Lock | Lock Modes Permitted? | ||||
---|---|---|---|---|---|---|
RS | RX | S | SRX | X | ||
SELECT...FROM table ... |
none | Y | Y | Y | Y | Y |
INSERT INTO table ... |
RX | Y | Y | N | N | N |
UPDATE table ... |
RX | Y* | Y* | N | N | N |
DELETE FROM table ... |
RX | Y* | Y* | N | N | N |
SELECT ... FROM table FOR UPDATE OF ... |
RS | Y* | Y* | Y* | Y* | N |
LOCK TABLE table IN ROW SHARE MODE |
RS | Y | Y | Y | Y | N |
LOCK TABLE table IN ROW EXCLUSIVE MODE |
RX | Y | Y | N | N | N |
LOCK TABLE table IN SHARE MODE |
S | Y | N | Y | N | N |
LOCK TABLE table IN SHARE ROW EXCLUSIVE MODE |
SRX | Y | N | N | N | N |
LOCK TABLE table IN EXCLUSIVE MODE |
X | N | N | N | N | N |
RS: row share
RX: row exclusive
S: share
SRX: share row exclusive
X: exclusive
*Yes, if no conflicting row locks are held by another transaction. Otherwise, waits occur.
行共享锁(RS)
行共享锁意味着事务在表上持有锁并打算更新他们。使用下面的语句的时候获取的。
select ..from table ..for update of..;
lock table table in row share mode;
row exclusize table locks(rx)
rx 意味着事务持有锁要更新一行或多行。通过下面的语句获取
INSERT INTO table ... ; UPDATE table ... ; DELETE FROM table ... ; LOCK TABLE table IN ROW EXCLUSIVE MODE;
share row exclusize table locks(SRX)
共享行排他锁,在一个时间一个表上只能有一个事务能获取共享行排他锁。持有该锁的事务可以让别的事务查询或锁定具体行使用select ..for update,但不能更新。
DML锁自动被dml操作获取
Table 13-4 Locks Obtained By DML Statements
DML Statement | Row Locks? | Mode of Table Lock |
---|---|---|
SELECT ... FROM table |
||
INSERT INTO table ... |
X | RX |
UPDATE table ... |
X | RX |
DELETE FROM table ... |
X | RX |
SELECT ... FROM table ... FOR UPDATE OF ... |
X | RS |
LOCK TABLE table IN ... |
||
ROW SHARE MODE |
RS | |
ROW EXCLUSIVE MODE |
RX | |
SHARE MODE |
S | |
SHARE EXCLUSIVE MODE |
SRX | |
EXCLUSIVE MODE |
X |
ddl锁分3种 排他ddl锁,共享ddl锁,和易碎解析锁
共享的ddl锁需要排他锁来保护资源不受损坏。比如在执行alter table期间不可以执行drop table.如果在获取排他ddl锁的时候,别的ddl锁已经在该对象上持有了锁,那么请求就会等待,直到别的ddl锁是否。
共享ddl锁
一些ddl操作需要共享ddl锁来保护资源不被损坏,允许在对象上执行相似的ddl操作。比如。当一个create procedure运行的时候,事务要求一个共享ddl锁。别的事务可以并发的在相同的表上创建存储过程,因此在相同的表上要获取共享锁,但是没有事务可以获取排他ddl锁。没有事务可以alter 或drop相关表。因此共享ddl保证了相关对象的定义在事务过程中依然不变。
共享ddl在下面的语句中获取:audit,noaudit,commnet,create [or replace] view/procedure/package/package body/function/triger,create synonym,与create table
易破碎解析锁
在共享池中的一个sql语句 对每个相关的对象持有一个解析锁,当相关对象被改变或删除的时候,解析锁能确保这些对象变无效。在sql执行的时候要获取解析锁,只要在共享sql区有这个语句,该锁就一直存在。
latches
latches是简单,低级别的串行机制用来保护在sga中的共享数据结构。
内部锁
内部锁是高级,更加复杂的机制,有不同的目的。
字典缓存锁
这些锁时间很短,在数据字典条目被修改或使用的时候获取。他们保证语句在解析的时候不会看到非连续的对象定义。字典缓存锁可以使共享的或排他的。