Apress.Expert.Oracle.Database.Architecture.9i.and.10g.Programming.Techniques.and.Solutions.Sep.2005
CHAPTER 6 ■ LOCKING AND LATCHING 229 Manual Locking and User-Defined Locks So far we have looked mostly at locks that Oracle places for us transparently. When we update a table, Oracle places a TM lock on it to prevent other sessions from dropping that table (or performing most DDL, in fact). We have TX locks that are left on the various blocks we modify so others can tell what data we “own.” The database employs DDL locks to protect objects from change while we ourselves are changing them. It uses latches and locks internally to protect its own structure. Next, let’s take a look at how we can get involved in some of this locking action. Our options are as follows: • Manually lock data via a SQL statement. • Create our own locks via the DBMS_LOCK package. In the following sections, we will briefly discuss why you might want to do each of these. Manual Locking We have, in fact, already seen a couple of cases where we might want to use manual locking. The SELECT...FOR UPDATE statement is the predominant method of manually locking data. We used it in previous examples to avoid the lost update issue, whereby one session would overwrite another session’s changes. We’ve seen it used as a method to serialize access to detail records to enforce business rules (e.g., the resource scheduler example from Chapter 1). We can also manually lock data using the LOCK TABLE statement. This statement is actually used rarely, because of the coarseness of the lock. It simply locks the table, not the rows in the table. If you start modifying the rows, they will be “locked” as normal. So, this is not a method to save on resources (as it might be in other RDBMSs). You might use the LOCK TABLE IN EXCLUSIVE MODE statement if you were writing a large batch update that would affect most of the rows in a given table and you wanted to be sure that no one would “block” you. By locking the table in this manner, you can be assured that your update will be able to do all of its work without getting blocked by other transactions. It would be the rare application, however, that has a LOCK TABLE statement in it. Creating Your Own Locks Oracle actually exposes to developers the enqueue lock mechanism that it uses internally, via the DBMS_LOCK package. You might be wondering why you would want to create your own locks. The answer is typically application specific. For example, you might use this package to serialize access to some resource external to Oracle. Say you are using the UTL_FILE routine that allows you to write to a file on the server’s file system. You might have developed a common message routine that every application calls to record messages. Since the file is external, Oracle won’t coordinate the many users trying to modify it simultaneously. In comes the DBMS_LOCK package. Now, before you open, write, and close the file, you will request a lock named after the file in exclusive mode, and after you close the file, you will manually release the lock. In this fashion, only one person at a time will be able to write a message to this file. Everyone else will queue up. The DBMS_LOCK package allows you to manually release a lock when you are done with it, or to give it up automatically when you commit, or even to keep it as long as you are logged in.
230 CHAPTER 6 ■ LOCKING AND LATCHING Summary This chapter covered a lot of material that, at times, may have made you scratch your head. While locking is rather straightforward, some of its side effects are not. However, it is vital that you understand these issues. For example, if you were not aware of the table lock Oracle uses to enforce a foreign key relationship when the foreign key is not indexed, then your application would suffer from poor performance. If you did not understand how to review the data dictionary to see who was locking whom, you might never figure that one out. You would just assume that the database “hangs” sometimes. I sometimes wish I had a dollar for every time I was able to solve the insolvable hanging issue by simply running the query to detect unindexed foreign keys and suggesting that we index the one causing the problem—I would be very rich.
- Page 224 and 225: CHAPTER 5 ■ ORACLE PROCESSES 179
- Page 226 and 227: CHAPTER 5 ■ ORACLE PROCESSES 181
- Page 228 and 229: CHAPTER 6 ■ ■ ■ Locking and L
- Page 230 and 231: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 232 and 233: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 234 and 235: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 236 and 237: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 238 and 239: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 240 and 241: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 242 and 243: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 244 and 245: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 246 and 247: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 248 and 249: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 250 and 251: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 252 and 253: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 254 and 255: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 256 and 257: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 258 and 259: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 260 and 261: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 262 and 263: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 264 and 265: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 266 and 267: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 268 and 269: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 270 and 271: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 272 and 273: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 276 and 277: CHAPTER 7 ■ ■ ■ Concurrency a
- Page 278 and 279: CHAPTER 7 ■ CONCURRENCY AND MULTI
- Page 280 and 281: CHAPTER 7 ■ CONCURRENCY AND MULTI
- Page 282 and 283: CHAPTER 7 ■ CONCURRENCY AND MULTI
- Page 284 and 285: CHAPTER 7 ■ CONCURRENCY AND MULTI
- Page 286 and 287: CHAPTER 7 ■ CONCURRENCY AND MULTI
- Page 288 and 289: CHAPTER 7 ■ CONCURRENCY AND MULTI
- Page 290 and 291: CHAPTER 7 ■ CONCURRENCY AND MULTI
- Page 292 and 293: CHAPTER 7 ■ CONCURRENCY AND MULTI
- Page 294 and 295: CHAPTER 7 ■ CONCURRENCY AND MULTI
- Page 296 and 297: CHAPTER 7 ■ CONCURRENCY AND MULTI
- Page 298 and 299: CHAPTER 7 ■ CONCURRENCY AND MULTI
- Page 300 and 301: CHAPTER 8 ■ ■ ■ Transactions
- Page 302 and 303: CHAPTER 8 ■ TRANSACTIONS 257 •
- Page 304 and 305: CHAPTER 8 ■ TRANSACTIONS 259 So,
- Page 306 and 307: CHAPTER 8 ■ TRANSACTIONS 261 X --
- Page 308 and 309: CHAPTER 8 ■ TRANSACTIONS 263 “s
- Page 310 and 311: CHAPTER 8 ■ TRANSACTIONS 265 busi
- Page 312 and 313: CHAPTER 8 ■ TRANSACTIONS 267 Many
- Page 314 and 315: CHAPTER 8 ■ TRANSACTIONS 269 ops$
- Page 316 and 317: CHAPTER 8 ■ TRANSACTIONS 271 last
- Page 318 and 319: CHAPTER 8 ■ TRANSACTIONS 273 Dist
- Page 320 and 321: CHAPTER 8 ■ TRANSACTIONS 275 Auto
- Page 322 and 323: CHAPTER 8 ■ TRANSACTIONS 277 3 Au
CHAPTER 6 ■ LOCKING AND LATCHING 229<br />
Manual Locking <strong>and</strong> User-Defined Locks<br />
So far we have looked mostly at locks that <strong>Oracle</strong> places for us transparently. When we update<br />
a table, <strong>Oracle</strong> places a TM lock on it to prevent other sessions from dropping that table (or<br />
performing most DDL, in fact). We have TX locks that are left on the various blocks we modify<br />
so others can tell what data we “own.” The database employs DDL locks to protect objects<br />
from change while we ourselves are changing them. It uses latches <strong>and</strong> locks internally to<br />
protect its own structure.<br />
Next, let’s take a look at how we can get involved in some of this locking action. Our<br />
options are as follows:<br />
• Manually lock data via a SQL statement.<br />
• Create our own locks via the DBMS_LOCK package.<br />
In the following sections, we will briefly discuss why you might want to do each of these.<br />
Manual Locking<br />
We have, in fact, already seen a couple of cases where we might want to use manual locking.<br />
The SELECT...FOR UPDATE statement is the predominant method of manually locking data. We<br />
used it in previous examples to avoid the lost update issue, whereby one session would overwrite<br />
another session’s changes. We’ve seen it used as a method to serialize access to detail<br />
records to enforce business rules (e.g., the resource scheduler example from Chapter 1).<br />
We can also manually lock data using the LOCK TABLE statement. This statement is actually<br />
used rarely, because of the coarseness of the lock. It simply locks the table, not the rows in<br />
the table. If you start modifying the rows, they will be “locked” as normal. So, this is not a<br />
method to save on resources (as it might be in other RDBMSs). You might use the LOCK TABLE<br />
IN EXCLUSIVE MODE statement if you were writing a large batch update that would affect most of<br />
the rows in a given table <strong>and</strong> you wanted to be sure that no one would “block” you. By locking<br />
the table in this manner, you can be assured that your update will be able to do all of its work<br />
without getting blocked by other transactions. It would be the rare application, however, that<br />
has a LOCK TABLE statement in it.<br />
Creating Your Own Locks<br />
<strong>Oracle</strong> actually exposes to developers the enqueue lock mechanism that it uses internally,<br />
via the DBMS_LOCK package. You might be wondering why you would want to create your own<br />
locks. The answer is typically application specific. For example, you might use this package<br />
to serialize access to some resource external to <strong>Oracle</strong>. Say you are using the UTL_FILE routine<br />
that allows you to write to a file on the server’s file system. You might have developed a<br />
common message routine that every application calls to record messages. Since the file is<br />
external, <strong>Oracle</strong> won’t coordinate the many users trying to modify it simultaneously. In comes<br />
the DBMS_LOCK package. Now, before you open, write, <strong>and</strong> close the file, you will request a lock<br />
named after the file in exclusive mode, <strong>and</strong> after you close the file, you will manually release<br />
the lock. In this fashion, only one person at a time will be able to write a message to this file.<br />
Everyone else will queue up. The DBMS_LOCK package allows you to manually release a lock<br />
when you are done with it, or to give it up automatically when you commit, or even to keep<br />
it as long as you are logged in.