05.11.2015 Views

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

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

200<br />

CHAPTER 6 ■ LOCKING AND LATCHING<br />

Optimistic or Pessimistic Locking?<br />

So which method is best? In my experience, pessimistic locking works very well in <strong>Oracle</strong> (but<br />

perhaps not in other databases) <strong>and</strong> has many advantages over optimistic locking. However, it<br />

requires a stateful connection to the database, like a client/server connection. This is because<br />

locks are not held across connections. This single fact makes pessimistic locking unrealistic in<br />

many cases today. In the past, with client/server applications <strong>and</strong> a couple dozen or hundred<br />

users, it would have been my first <strong>and</strong> only choice. Today, however, optimistic concurrency<br />

control is what I would recommend for most applications. Having a connection for the entire<br />

duration of a transaction is just too high a price to pay.<br />

Of the methods available, which do I use? I tend to use the version column approach with<br />

a timestamp column. It gives me the extra information “when was this row last updated” in a<br />

long-term sense. So it adds value in that way. It is less computationally expensive than a hash<br />

or checksum, <strong>and</strong> it doesn’t run into the issues potentially encountered with a hash or checksum<br />

when processing LONG, LONG RAW, CLOB, BLOB, <strong>and</strong> other very large columns.<br />

If I had to add optimistic concurrency controls to a table that was still being used with a<br />

pessimistic locking scheme (e.g., the table was accessed in both client/server applications <strong>and</strong><br />

over the Web), I would opt for the ORA_ROWSCN approach. The reason is that the existing legacy<br />

application might not appreciate a new column appearing, or even if we took the additional<br />

step of hiding the extra column, we might not appreciate the overhead of the necessary trigger<br />

to maintain it. The ORA_ROWSCN technique would be nonintrusive <strong>and</strong> lightweight in that<br />

respect (well, after we get over the table re-creation, that is).<br />

The hashing/checksum approach is very database independent, especially if we compute<br />

the hashes or checksums outside of the database. However, by performing the computations<br />

in the middle tier rather than the database, we will incur higher resource usage penalties, in<br />

terms of CPU usage <strong>and</strong> network transfers.<br />

Blocking<br />

Blocking occurs when one session holds a lock on a resource that another session is requesting.<br />

As a result, the requesting session will be blocked—it will “hang” until the holding session<br />

gives up the locked resource. In almost every case, blocking is avoidable. In fact, if you do find<br />

that your session is blocked in an interactive application, then you have probably been suffering<br />

from the lost update bug as well, perhaps without realizing it. That is, your application<br />

logic is flawed <strong>and</strong> that is the cause of the blocking.<br />

The five common DML statements that will block in the database are INSERT, UPDATE,<br />

DELETE, MERGE, <strong>and</strong> SELECT FOR UPDATE. The solution to a blocked SELECT FOR UPDATE is trivial:<br />

simply add the NOWAIT clause <strong>and</strong> it will no longer block. Instead, your application will report<br />

back to the end user that the row is already locked. The interesting cases are the remaining<br />

four DML statements. We’ll look at each of them <strong>and</strong> see why they should not block <strong>and</strong> how<br />

to correct the situation if they do.<br />

Blocked Inserts<br />

There are few times when an INSERT will block. The most common scenario is when you have<br />

a table with a primary key or unique constraint placed on it <strong>and</strong> two sessions attempt to insert<br />

a row with the same value. One of the sessions will block until the other session either commits<br />

(in which case the blocked session will receive an error about a duplicate value) or rolls

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

Saved successfully!

Ooh no, something went wrong!