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 8 ■ TRANSACTIONS 273<br />

Distributed Transactions<br />

One of the really nice features of <strong>Oracle</strong> is its ability to transparently h<strong>and</strong>le distributed transactions.<br />

I can update data in many different databases in the scope of a single transaction.<br />

When I commit, either I commit the updates in all of the instances or I commit none of them<br />

(they will all be rolled back). I need no extra code to achieve this; I simply “commit.”<br />

A key to distributed transactions in <strong>Oracle</strong> is the database link. A database link is a database<br />

object that describes how to log into another instance from your instance. However, the<br />

purpose of this section is not to cover the syntax of the database link comm<strong>and</strong> (it is fully documented),<br />

but rather to expose you to its very existence. Once you have a database link set up,<br />

accessing remote objects is as easy as this:<br />

select * from T@another_database;<br />

This would select from table T in the database instance defined by the database link<br />

ANOTHER_DATABASE. Typically, you would “hide” the fact that T is a remote table by creating a<br />

view of it, or a synonym. For example, I can issue the following <strong>and</strong> then access T as if it were<br />

a local table:<br />

create synonym T for T@another_database;<br />

Now that I have this database link set up <strong>and</strong> can read some tables, I am also able to modify<br />

them (given that I have the appropriate privileges, of course). Performing a distributed<br />

transaction is now no different from a local transaction. All I would do is this:<br />

update local_table set x = 5;<br />

update remote_table@another_database set y = 10;<br />

commit;<br />

That’s it. <strong>Oracle</strong> will commit either in both databases or in neither. It uses a 2PC protocol<br />

to do this. 2PC is a distributed protocol that allows for a modification that affects many disparate<br />

databases to be committed atomically. It attempts to close the window for distributed<br />

failure as much as possible before committing. In a 2PC between many databases, one of the<br />

databases—typically the one the client is logged into initially—will be the coordinator for the<br />

distributed transaction. This one site will ask the other sites if they are ready to commit. In<br />

effect, this one site will go to the other sites <strong>and</strong> ask them to be prepared to commit. Each of<br />

the other sites reports back its “prepared state” as YES or NO. If any one of the sites votes NO, the<br />

entire transaction is rolled back. If all sites vote YES, the site coordinator broadcasts a message<br />

to make the commit permanent on each of the sites.<br />

This limits the window in which a serious error could occur. Prior to the “voting” on the<br />

2PC, any distributed error would result in all of the sites rolling back. There would be no doubt<br />

as to the outcome of the transaction. After the order to commit or roll back, there again is no<br />

doubt as to the outcome of the distributed transaction. It is only during the very short window<br />

when the coordinator is collecting the votes that the outcome might be in doubt, after a failure.<br />

Assume, for example, we have three sites participating in the transaction with Site 1 being<br />

the coordinator. Site 1 has asked Site 2 to prepare to commit, <strong>and</strong> Site 2 has done so. Site 1<br />

then asks Site 3 to prepare to commit, <strong>and</strong> it does so. At this point in time, Site 1 is the only site

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

Saved successfully!

Ooh no, something went wrong!