Apress.Expert.Oracle.Database.Architecture.9i.and.10g.Programming.Techniques.and.Solutions.Sep.2005

rekharaghuram
from rekharaghuram More from this publisher
05.11.2015 Views

CHAPTER 6 ■ LOCKING AND LATCHING 215 ops$tkyte@ORA9IR2> commit; Commit complete. ops$tkyte@ORA9IR2> select distinct dbms_rowid.rowid_block_number(rowid) from t; DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) ------------------------------------ 18 So, we have 24 rows and we’ve verified they are all on the same database block. Now, in one session we issue ops$tkyte@ORA9IR2> update t set x = 1 where x = 1; 1 row updated. and in another, we issue ops$tkyte@ORA9IR2> update t set x = 2 where x = 2; 1 row updated. Finally, in a third session, we issue ops$tkyte@ORA9IR2> update t set x = 3 where x = 3; Now, since those three rows are on the same database block, and we set MAXTRANS (the maximum degree of concurrency for that block) to 2, the third session will be blocked. ■Note Remember, in Oracle 10g this blocking will not happen in this example—MAXTRANS is set to 255 regardless. There would have to be insufficient space on the block to grow the transaction table to see this blocking in that release. This example demonstrates what happens when more than one MAXTRANS transaction attempts to access the same block simultaneously. Similarly, blocking may also occur if the INITRANS is set low and there is not enough space on a block to dynamically expand the transaction. In most cases, the default of 2 for INITRANS is sufficient, as the transaction table will dynamically grow (space permitting), but in some environments you may need to increase this setting to increase concurrency and decrease waits. An example of when you might need to do this would be on a table or, even more frequently, on an index (since index blocks can get many more rows on them than a table can typically hold) that is frequently modified. You may need to increase either PCTFREE (discussed in Chapter 10) or INITRANS to set aside ahead of time sufficient space on the block for the number of expected concurrent transactions. This is especially true if you anticipate the blocks will be nearly full to begin with, meaning there is no room for the dynamic expansion of the transaction structure on the block.

216 CHAPTER 6 ■ LOCKING AND LATCHING TM (DML Enqueue) Locks TM locks are used to ensure that the structure of a table is not altered while you are modifying its contents. For example, if you have updated a table, you will acquire a TM lock on that table. This will prevent another user from executing DROP or ALTER commands on that table. If another user attempts to perform DDL on the table while you have a TM lock on it, he’ll receive the following error message: drop table dept * ERROR at line 1: ORA-00054: resource busy and acquire with NOWAIT specified This is a confusing message at first, since there is no method to specify NOWAIT or WAIT on a DROP TABLE at all. It is just the generic message you get when you attempt to perform an operation that would be blocked, but the operation does not permit blocking. As you’ve seen before, it’s the same message you get if you issue a SELECT FOR UPDATE NOWAIT against a locked row. The following shows how these locks would appear in the V$LOCK table: ops$tkyte@ORA10G> create table t1 ( x int ); Table created. ops$tkyte@ORA10G> create table t2 ( x int ); Table created. ops$tkyte@ORA10G> insert into t1 values ( 1 ); 1 row created. ops$tkyte@ORA10G> insert into t2 values ( 1 ); 1 row created. ops$tkyte@ORA10G> select (select username 2 from v$session 3 where sid = v$lock.sid) username, 4 sid, 5 id1, 6 id2, 7 lmode, 8 request, block, v$lock.type 9 from v$lock 10 where sid = (select sid 11 from v$mystat 12 where rownum=1) 13 /

216<br />

CHAPTER 6 ■ LOCKING AND LATCHING<br />

TM (DML Enqueue) Locks<br />

TM locks are used to ensure that the structure of a table is not altered while you are modifying<br />

its contents. For example, if you have updated a table, you will acquire a TM lock on that table.<br />

This will prevent another user from executing DROP or ALTER comm<strong>and</strong>s on that table. If<br />

another user attempts to perform DDL on the table while you have a TM lock on it, he’ll<br />

receive the following error message:<br />

drop table dept<br />

*<br />

ERROR at line 1:<br />

ORA-00054: resource busy <strong>and</strong> acquire with NOWAIT specified<br />

This is a confusing message at first, since there is no method to specify NOWAIT or WAIT<br />

on a DROP TABLE at all. It is just the generic message you get when you attempt to perform<br />

an operation that would be blocked, but the operation does not permit blocking. As you’ve<br />

seen before, it’s the same message you get if you issue a SELECT FOR UPDATE NOWAIT against a<br />

locked row.<br />

The following shows how these locks would appear in the V$LOCK table:<br />

ops$tkyte@ORA10G> create table t1 ( x int );<br />

Table created.<br />

ops$tkyte@ORA10G> create table t2 ( x int );<br />

Table created.<br />

ops$tkyte@ORA10G> insert into t1 values ( 1 );<br />

1 row created.<br />

ops$tkyte@ORA10G> insert into t2 values ( 1 );<br />

1 row created.<br />

ops$tkyte@ORA10G> select (select username<br />

2 from v$session<br />

3 where sid = v$lock.sid) username,<br />

4 sid,<br />

5 id1,<br />

6 id2,<br />

7 lmode,<br />

8 request, block, v$lock.type<br />

9 from v$lock<br />

10 where sid = (select sid<br />

11 from v$mystat<br />

12 where rownum=1)<br />

13 /

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!