为了确保并发用户在存取同一数据库对象时的正确性(即无丢失修改、可重复读、不读"脏"数据),
数据库中引入了锁机制。基本的锁类型有两种:排它锁(Exclusive locks记为X锁)和 共享锁
(Share locks记为S锁)。(表注1)
共享锁:若事务T对数据D加S锁,则其它事务只能对D加S锁,而不能加X锁,直至T释放D上的S锁;
一般要求在读取数据前要向该数据加共享锁,所以共享锁又称为读锁。(表注1)
排它锁:若事务T对数据D加X锁,则其它任何事务都不能再对D加任何类型的锁,直至T释放D上的X锁;
一般要求在修改数据前要向该数据加排它锁,所以排它锁又称为写锁。(表注1)
由于数据是存储在表里,所以,在对数据进行DML操作时,除了对被操作的数据加X锁外,对表结构
也需要加S锁,以防止别的SESSION对此表结构的更改或删除。ORACLE的原文是这样解释的:
If a transaction obtains a row lock for a row, the transaction also acquires a table lock
for the corresponding table. The table lock prevents conflicting DDL operations that would
override data changes in a current transaction.
又如,其对Table Locks -- (TM) 的解释:
A transaction acquires a table lock when a table is modified in the following DML
statements: INSERT, UPDATE, DELETE, SELECT with the FOR UPDATE clause, and LOCK TABLE. These
DML operations require table locks for two purposes: to reserve DML access to the table on
behalf of a transaction and to prevent DDL operations that would conflict with the
transaction. Any table lock prevents the acquisition of an exclusive DDL lock on the same
table and thereby prevents DDL operations that require such locks. For example, a table
cannot be altered or dropped if an uncommitted transaction holds a table lock for it.
对ORACLE定义的这7个级别的锁,我是这样理解的
LMODE -- Lock mode in which the session holds the lock:
0 - none ---- 无
1 - null (NULL) ---- 可能某些情况下,如分布式数据库的查询会产生此锁。
2 - row-S (SS) ---- 表结构共享锁
3 - row-X (SX) ---- 表结构共享锁+被操作的记录的排它锁(若有DML操作)
4 - share (S) ---- 表结构共享锁+所有记录共享锁(隐含)
5 - S/Row-X (SSX) ---- 表结构共享锁+所有记录排它锁(隐含)
6 - exclusive (X) ---- 表结构排它锁
ORACLE的文档中,对SS锁是这样解释的:
Row Share Table Locks (RS)
A row share table lock (also sometimes called a subshare table lock, SS) indicates that the
transaction holding the lock on the table has locked rows in the table and intends to update
them. A row share table lock is automatically acquired for a table when one of the following
SQL statements is executed:
SELECT ... FROM table ... FOR UPDATE OF ... ;
LOCK TABLE table IN ROW SHARE MODE;
按照上面的解释:是ORACLE锁住某表及该表的某些记录,准备(倾向)修改这些记录。
但尝试以 LOCK TABLE table IN ROW SHARE MODE 来锁住某表后,查看V$LOCK视图,发现只有TM=2的锁,
而并未对哪些记录加了S锁;比较SELECT FOR UPDATE,发现除了TM=2的锁外,还存在TX=6的锁,
并且通过TX=6中的ID1,ID2,可在回滚段中查看到被加了X锁的记录。此外,ORACLE文档中也
说明,被SS的表(TM=2的锁),其中的记录可以被DML,但不允许对该表加X锁;这说明,该表的
记录并未被加S锁(因为可以修改记录),而只是表结构加了S锁(因为不可以对表加X锁),故此,认定,
SS锁实际就是对表加S锁。
对于RX锁,通过DML操作后得知:DML操作会产生TX=6 和 TM=3的锁,从TX=6中的ID1,ID2,可在回滚段中
查看到被加了X锁的记录,而这些记录在未提交/回滚之前,是不可以再被修改的。通过对该表,
除了这些记录被加X锁外,别的记录仍可以被DML,这说明,表被加了S锁,被操作的记录被加了X锁。
因此认定,RS实际就是:表结构共享锁+被操作的记录的排它锁。当只是对表加RX锁时候。
S锁:由于加了S锁的表,无法对其数据进行DML操作,故猜测,S锁实际是对表结构和表记录加了
共享锁。对于加了S锁后,仍可以对表执行SELECT FOR UPDATE,我是这样理解的:SELECT FOR UPDATE
是比较特殊的一种情况:由于其不修改记录,所以对这些记录而言,并未产生真正的排它锁,这与DML操作
产生的排它锁相比,是有差别的;但由于不允许在这些记录“再”加SELECT FOR UPDATE,所以,也不是纯粹
的共享锁,我认为其是介于共享锁和排它锁之间的一种特殊的情况,因此,ORACLE在对表加了S锁后,还
允许对该表执行SELCT FOR UPDATE,但实际上,此时此语句已经无意义了,因为加了S锁的表不允许DML
操作,故,此语句于普通的SELECT 语句无差别。
SRX锁,第4级别是S锁(表结构共享锁+所有记录共享锁),第6级别是X锁(表结构排它锁+所有记录排它锁),
而根据锁级别不断升高,锁的限制不断加强的规律判断,SRX--第5层锁,只能是:表结构共享锁+所有记录
排它锁 这种情况。但目前,还想不出在什么情况下会使用这样的锁?
X锁:表结构排它锁。其实,表结构加排它锁后,表记录自然也算是加了排它锁,因为此时,表记录无法加
共享锁,只能只读。故,此锁级别最高,通常使用在修改表结构或删除表时使用。
阅读(3153) | 评论(0) | 转发(0) |