05.11.2015 Views

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

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

CHAPTER 8 ■ TRANSACTIONS 261<br />

X<br />

----------<br />

1<br />

ops$tkyte@ORA10G> select * from t2;<br />

CNT<br />

----------<br />

1<br />

Here, we ran a block of code that ignored any <strong>and</strong> all errors, <strong>and</strong> the difference in outcome<br />

is huge. Whereas the first call to P effected no changes, here the first INSERT succeeds<br />

<strong>and</strong> the CNT column in T2 is incremented accordingly.<br />

■Note I consider virtually all code that contains a WHEN OTHERS exception h<strong>and</strong>ler that does not also<br />

include a RAISE to re-raise the exception to be a bug. It silently ignores the error <strong>and</strong> it changes the transaction<br />

semantics. Catching WHEN OTHERS <strong>and</strong> translating the exception into an old-fashioned return code<br />

changes the way the database is supposed to behave.<br />

<strong>Oracle</strong> considered the “statement” to be the block that the client submitted. This statement<br />

succeeded by catching <strong>and</strong> ignoring the error itself, so the If error then rollback...<br />

didn’t come into effect <strong>and</strong> <strong>Oracle</strong> did not roll back to the SAVEPOINT after execution. Hence,<br />

the partial work performed by P was preserved. The reason that this partial work was preserved<br />

in the first place is that we have statement-level atomicity within P: each statement in<br />

P is atomic. P becomes the client of <strong>Oracle</strong> when it submits its two INSERT statements. Each<br />

INSERT either entirely succeeds or fails. This is evidenced by the fact that we can see that the<br />

trigger on T fired twice <strong>and</strong> updated T2 twice, yet the count in T2 reflects only one UPDATE. The<br />

second INSERT executed in P had an implicit SAVEPOINT wrapped around it.<br />

The difference between the two blocks of code is subtle <strong>and</strong> something you must consider<br />

in your applications. Adding an exception h<strong>and</strong>ler to a block of PL/SQL code can radically<br />

change its behavior. A different way to code this—one that restores the statement-level atomicity<br />

to the entire PL/SQL block—is as follows:<br />

ops$tkyte@ORA10G> begin<br />

2 savepoint sp;<br />

3 p;<br />

4 exception<br />

5 when others then<br />

6 rollback to sp;<br />

7 end;<br />

8 /<br />

I fired <strong>and</strong> updated 1 rows<br />

I fired <strong>and</strong> updated 1 rows

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

Saved successfully!

Ooh no, something went wrong!