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.

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

• Consider a trigger that maintains some PL/SQL global variables, such as the number of<br />

rows processed. When a statement that restarts rolls back, the modifications to PL/SQL<br />

variables won’t “roll back.”<br />

• Virtually any function that starts with UTL_ (UTL_FILE, UTL_HTTP, UTL_SMTP, <strong>and</strong> so on)<br />

should be considered susceptible to a statement restart. When the statement restarts,<br />

UTL_FILE won’t “un-write” to the file it was writing to.<br />

• Any trigger that is part of an autonomous transaction must be suspect. When the statement<br />

restarts <strong>and</strong> rolls back, the autonomous transaction cannot be rolled back.<br />

All of these consequences must be h<strong>and</strong>led with care in the belief that they may be fired<br />

more than once per row or be fired for a row that won’t be updated by the statement after all.<br />

The second reason you should care about potential restarts is performance related. We<br />

have been using a single-row example, but what happens if you start a large batch update<br />

<strong>and</strong> it is restarted after processing the first 100,000 records? It will roll back the 100,000 row<br />

changes, restart in SELECT FOR UPDATE mode, <strong>and</strong> do the 100,000 row changes again after that.<br />

You might notice, after putting in that simple audit trail trigger (the one that reads the<br />

:NEW <strong>and</strong> :OLD values), that performance is much worse than you can explain, even though<br />

nothing else has changed except the new triggers. It could be that you are restarting queries<br />

you never used to in the past. Or the addition of a tiny program that updates just a single row<br />

here <strong>and</strong> there makes a batch process that used to run in an hour suddenly run in many hours<br />

due to restarts that never used to take place.<br />

This is not a new feature of <strong>Oracle</strong>—it has been in the database since version 4.0, when<br />

read consistency was introduced. I myself was not totally aware of how it worked until the<br />

summer of 2003 <strong>and</strong>, after I discovered what it implied, I was able to answer a lot of “How<br />

could that have happened?” questions from my own past. It has made me swear off using<br />

autonomous transactions in triggers almost entirely, <strong>and</strong> it has made me rethink the way<br />

some of my applications have been implemented. For example, I’ll never send e-mail from a<br />

trigger directly; rather, I’ll always use DBMS_JOB or the new <strong>Oracle</strong> 10g scheduler facility to send<br />

the e-mail after my transaction commits. This makes the sending of the e-mail “transactional”—that<br />

is, if the statement that caused the trigger to fire <strong>and</strong> send the e-mail is restarted,<br />

the rollback it performs will roll back the DBMS_JOB request. Most everything nontransactional<br />

that I did in triggers was modified to be done in a job after the fact, making it all transactionally<br />

consistent.<br />

Summary<br />

In this chapter, we covered a lot of material that, at times, likely made you scratch your head.<br />

However, it is vital that you underst<strong>and</strong> these issues. For example, if you were not aware of the<br />

statement-level restart, you might not be able to figure out how a certain set of circumstances<br />

could have taken place. That is, you would not be able to explain some of the daily empirical<br />

observations you make. In fact, if you were not aware of the restarts, you might wrongly suspect<br />

the actual fault to be due to the circumstances or an end user error. It would be one of<br />

those unreproducible issues, as it takes many things happening in a specific order to observe.

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

Saved successfully!

Ooh no, something went wrong!