On Thu, Oct 06, 2011 at 03:20:08PM -0700, Eirik Toft wrote:
> On Sep 13, 11:16 am, mark.bo...@proquest.com ("Bobak, Mark") wrote:
> > Does anyone have any experience w/ doing two-phase commit across
> > connections to two different databases from the same Perl program?
> >  (To guarantee that either both or neither transaction is committed,
> > for consistency.)
> 
> Well, assuming you have AutoCommit turned off, why not....

> unless ($sth1->execute("this","that") && $sth2->execute("this","that")) {
>   $dbh1->rollback;
>   $dbh2->rollback;
> } else {
>   $dbh1->commit;
>   $dbh2->commit;
> }

Because if the second commit fails (for any of countless reasons) the
first commit can't be rolled back.

Mark, there's no explicit support for two-phase commit in the DBI, but
drivers are free to implement support via private methods. I don't know
off hand if any do. After a very quick skim of the OCI docs at
http://www.tacsoft.cn/1110/appdev.111/b28395/oci17msc006.htm
it might be fairly simple to add to DBD::Oracle.

Something like:

  ...as above...
  else {
    try {
        $dbh1->ora_trans_prepare();                  # OCITransPrepare()
        $dbh2->ora_trans_prepare();
        $dbh1->ora_trans_commit(OCI_TRANS_TWOPHASE); # OCITransCommit()
        $dbh2->ora_trans_commit(OCI_TRANS_TWOPHASE);
    }
    catch {
        $dbh1->ora_trans_forget();                   # OCITransForget()
        $dbh2->ora_trans_forget();
    }
  }

[assuming RaiseError is enabled and Try::Tiny has been use'd.]
Would be nice to add the rest of the OCITrans*() calls as well.

Tim.

Reply via email to