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.

266<br />

CHAPTER 8 ■ TRANSACTIONS<br />

This allows you to have robust transactions in the database. These transactions do not have<br />

to be short in duration—they should be exactly as long as they need to be (but no longer).<br />

Transactions are not for the convenience of the computer <strong>and</strong> its software; they are to protect<br />

your data.<br />

Committing in a Loop<br />

Faced with the task of updating many rows, most programmers will try to figure out some procedural<br />

way to do it in a loop, so that they can commit every so many rows. I’ve heard two<br />

main reasons for doing it this way:<br />

• It is faster <strong>and</strong> more efficient to frequently commit lots of small transactions than it is to<br />

process <strong>and</strong> commit one big transaction.<br />

• We don’t have enough undo space.<br />

Both of these conclusions are misguided. Furthermore, committing too frequently leaves<br />

you prone to the danger of leaving your database in an “unknown” state should your update<br />

fail halfway through. It requires complex logic to write a process that is smoothly restartable<br />

in the event of failure. By far the best option is to commit only as frequently as your business<br />

processes dictate <strong>and</strong> to size your undo segments accordingly.<br />

Let’s take a look at these issues in more detail.<br />

Performance Implications<br />

It is generally not faster to commit frequently—it is almost always faster to do the work in a<br />

single SQL statement. By way of a small example, say we have a table, T, with lots of rows, <strong>and</strong><br />

we want to update a column value for every row in that table. We’ll use two tables, T1 <strong>and</strong> T2,<br />

to demonstrate:<br />

ops$tkyte@ORA10G> create table t1 as select * from all_objects;<br />

Table created.<br />

ops$tkyte@ORA10G> exec dbms_stats.gather_table_stats( user, 'T1' );<br />

PL/SQL procedure successfully completed.<br />

ops$tkyte@ORA10G> create table t2 as select * from t1;<br />

Table created.<br />

ops$tkyte@ORA10G> exec dbms_stats.gather_table_stats( user, 'T2' );<br />

PL/SQL procedure successfully completed.<br />

Well, when we go to update, we could simply do it in a single UPDATE statement, like this:<br />

ops$tkyte@ORA10G> set timing on<br />

ops$tkyte@ORA10G> update t1 set object_name = lower(object_name);<br />

48306 rows updated.<br />

Elapsed: 00:00:00.31

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

Saved successfully!

Ooh no, something went wrong!