简体   繁体   中英

Two transactions on two databases

I need to put multiple values into 2 databases. The thing is, that if one of those INSERTS fails, i need all the other to rollback.

The question Is it possible, to make simultaneously two transactions, inserting some values into databases, and then Commit or rollback both of them?

The Code

$res = new ResultSet(); //class connecting and letting me query first database
$res2 = new ResultSet2(); //the other database
$res->query("BEGIN");
$res2->query("BEGIN");

try
{
    $res->query("INSERT xxx~~") or wyjatek('rollback'); //wyjatek is throwing exception if query fails
    $res2->query("INSERT yyy~~")or wyjatek('rollback');
    ......
    //if everything goes well
    $res->query("COMMIT");
    $res2->query("COMMIT");
    //SHOW some GREEN text saying its done.
}
catch(Exception $e)
{
   //if wyjatek throws an exception
   $res->query("ROLLBACK");
   $res2->query("ROLLBACK");
   //SHOW some RED text, saying it failed
}

Summary So is it proper way, or will it even work?

All tips appreciated.

Theoretically

If you will remove

or wyjatek('rollback')

your script will be work.

But looking to documentation

Transactions are isolated within a single "database". If you want to use multiple database transactions using MySql you can see XA Transactions .

Support for XA transactions is available for the InnoDB storage engine.

XA supports distributed transactions, that is, the ability to permit multiple separate transactional resources to participate in a global transaction. Transactional resources often are RDBMSs but may be other kinds of resources.

An application performs actions that involve different database servers, such as a MySQL server and an Oracle server (or multiple MySQL servers), where actions that involve multiple servers must happen as part of a global transaction, rather than as separate transactions local to each server.

The XA Specification. This document is published by The Open Group and available at http://www.opengroup.org/public/pubs/catalog/c193.htm

What you propose will almost always work. But for some uses, 'almost always' is not good enough.

If you have deferred constraints, the commit on $res2 could fail on a constraint violation, and then it is too late to rollback $res.

Or, one of your servers or the network could fail between the first commit and the second. If the php, database1, and database2 are all on the same hardware, the window for this failure mode is pretty small, but not negligible.

If 'almost always' is not good enough, and you cannot migrate one set of data to live inside the other database, then you might need to resort to "prepared transactions".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM