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 7 ■ CONCURRENCY AND MULTI-VERSIONING 239 Lost Updates: Another Portability Issue A common use of REPEATABLE READ in databases that employ the shared read locks could be for lost update prevention. ■Note Lost update detection and solutions to the lost update problem are discussed in Chapter 6. If we have REPEATABLE READ enabled in a database that employs shared read locks (and not multi-versioning), lost update errors cannot happen. The reason lost updates cannot happen in those databases is because the simple act of selecting the data left a lock on it, once read by our transaction, that data cannot be modified by any other transaction. Now, if your application assumes that REPEATABLE READ implies “lost updates cannot happen,” you are in for a painful surprise when you move your application to a database that does not use shared read locks as an underlying concurrency-control mechanism. While this sounds good, you must remember that leaving the shared read locks behind on all data as it is read will, of course, severely limit concurrent reads and modifications. So, while this isolation level in those databases provides for lost update prevention, it does so by removing the ability to perform concurrent operations! You cannot always have your cake and eat it too. SERIALIZABLE This is generally considered the most restrictive level of transaction isolation, but it provides the highest degree of isolation. A SERIALIZABLE transaction operates in an environment that makes it appear as if there are no other users modifying data in the database. Any row we read is assured to be the same upon a reread, and any query we execute is guaranteed to return the same results for the life of a transaction. For example, if we execute Select * from T; Begin dbms_lock.sleep( 60*60*24 ); end; Select * from T; the answers returned from T would be the same, even though we just slept for 24 hours (or we might get an ORA-1555: snapshot too old error, which is discussed in Chapter 8). The isolation level assures us these two queries will always return the same results. Side effects (changes) made by other transactions are not visible to the query regardless of how long it has been running. In Oracle, a SERIALIZABLE transaction is implemented so that the read consistency we normally get at the statement level is extended to the transaction. ■Note As noted earlier, there is also an isolation level in Oracle denoted READ ONLY. It has all of the qualities of the SERIALIZABLE isolation level, but it prohibits modifications. It should be noted that the SYS user (or users connected as SYSDBA) cannot have a READ ONLY or SERIALIZABLE transaction. SYS is special in this regard.

240 CHAPTER 7 ■ CONCURRENCY AND MULTI-VERSIONING Instead of results being consistent with respect to the start of a statement, they are preordained at the time you begin the transaction. In other words, Oracle uses the rollback segments to reconstruct the data as it existed when our transaction began, instead of just when our statement began. That’s a pretty deep thought there—the database already knows the answer to any question you might ask it, before you ask it. This degree of isolation comes with a price, and that price is the following possible error: ERROR at line 1: ORA-08177: can't serialize access for this transaction You will get this message whenever you attempt to update a row that has changed since your transaction began. ■Note Oracle attempts to do this purely at the row level, but you may receive an ORA-01877 error even when the row you are interested in modifying has not been modified. The ORA-01877 error may happen due to some other row(s) being modified on the block that contains your row. Oracle takes an optimistic approach to serialization—it gambles on the fact that the data your transaction wants to update won’t be updated by any other transaction. This is typically the way it happens, and usually the gamble pays off, especially in quick-transaction, OLTPtype systems. If no one else updates your data during your transaction, this isolation level, which will generally decrease concurrency in other systems, will provide the same degree of concurrency as it would without SERIALIZABLE transactions. The downside to this is that you may get the ORA-08177 error if the gamble doesn’t pay off. If you think about it, however, it’s worth the risk. If you’re using a SERIALIZABLE transaction, you shouldn’t expect to update the same information as other transactions. If you do, you should use the SELECT ... FOR UPDATE as described previously in Chapter 1, and this will serialize the access. So, using an isolation level of SERIALIZABLE will be achievable and effective if you • Have a high probability of no one else modifying the same data • Need transaction-level read consistency • Will be doing short transactions (to help make the first bullet point a reality) Oracle finds this method scalable enough to run all of their TPC-Cs (an industry standard OLTP benchmark; see www.tpc.org for details). In many other implementations, you will find this being achieved with shared read locks and their corresponding deadlocks, and blocking. Here in Oracle, we do not get any blocking, but we will get the ORA-08177 error if other sessions change the data we want to change as well. However, we will not get the error as frequently as we will get deadlocks and blocks in the other systems. But—there is always a “but”—you must take care to understand these different isolation levels and their implications. Remember, with isolation set to SERIALIZABLE, you will not see any changes made in the database after the start of your transaction, until you commit. Applications that attempt to enforce their own data integrity constraints, such as the resource scheduler described in Chapter 1, must take extra care in this regard. If you recall, the problem

CHAPTER 7 ■ CONCURRENCY AND MULTI-VERSIONING 239<br />

Lost Updates: Another Portability Issue<br />

A common use of REPEATABLE READ in databases that employ the shared read locks could be for<br />

lost update prevention.<br />

■Note Lost update detection <strong>and</strong> solutions to the lost update problem are discussed in Chapter 6.<br />

If we have REPEATABLE READ enabled in a database that employs shared read locks (<strong>and</strong> not<br />

multi-versioning), lost update errors cannot happen. The reason lost updates cannot happen<br />

in those databases is because the simple act of selecting the data left a lock on it, once read by<br />

our transaction, that data cannot be modified by any other transaction. Now, if your application<br />

assumes that REPEATABLE READ implies “lost updates cannot happen,” you are in for a<br />

painful surprise when you move your application to a database that does not use shared read<br />

locks as an underlying concurrency-control mechanism.<br />

While this sounds good, you must remember that leaving the shared read locks behind on<br />

all data as it is read will, of course, severely limit concurrent reads <strong>and</strong> modifications. So, while<br />

this isolation level in those databases provides for lost update prevention, it does so by removing<br />

the ability to perform concurrent operations! You cannot always have your cake <strong>and</strong> eat<br />

it too.<br />

SERIALIZABLE<br />

This is generally considered the most restrictive level of transaction isolation, but it provides<br />

the highest degree of isolation. A SERIALIZABLE transaction operates in an environment that<br />

makes it appear as if there are no other users modifying data in the database. Any row we read<br />

is assured to be the same upon a reread, <strong>and</strong> any query we execute is guaranteed to return the<br />

same results for the life of a transaction. For example, if we execute<br />

Select * from T;<br />

Begin dbms_lock.sleep( 60*60*24 ); end;<br />

Select * from T;<br />

the answers returned from T would be the same, even though we just slept for 24 hours (or we<br />

might get an ORA-1555: snapshot too old error, which is discussed in Chapter 8). The isolation<br />

level assures us these two queries will always return the same results. Side effects (changes)<br />

made by other transactions are not visible to the query regardless of how long it has been<br />

running.<br />

In <strong>Oracle</strong>, a SERIALIZABLE transaction is implemented so that the read consistency we<br />

normally get at the statement level is extended to the transaction.<br />

■Note As noted earlier, there is also an isolation level in <strong>Oracle</strong> denoted READ ONLY. It has all of the qualities<br />

of the SERIALIZABLE isolation level, but it prohibits modifications. It should be noted that the SYS user<br />

(or users connected as SYSDBA) cannot have a READ ONLY or SERIALIZABLE transaction. SYS is special in<br />

this regard.

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

Saved successfully!

Ooh no, something went wrong!