Synchronous clones or simple distributed transactions (PHP)

    For a long time I tried to put into words why I needed all this, but then I abandoned this idea. Who cares - I will answer in the comments. So the bottom line:

    There are several web sites with a similar database, with similar functionality (for example, stores selling the same products (one owner).

    You need to: add a new product to all stores at the same time. Or do not add anywhere in case of an error on one. If it’s quite simple, then the record IDs in certain tables should match on all sites, for example, product_id. Again, I’ve simplified the task, in fact, it’s much more complicated.


    Suppose there is a Product class on each site and the corresponding method That is, on each site a new the record is created like this:

    class Product
    {
    ...
    public static function createNewProduct($productName)
    {
    if ( self::exists($productName) ) {
    throw new Exception('product exists in database');
    //выбрасывание исключения добавлено неслучайно
    // а для того, чтобы показать что «иногда что-то может пойти не так»
    }

    $db->execute(
    'INSERT INTO products
    SET name={$productName}');
    $newId = $db->lastInsertId;

    return new self($newId);
    }
    ...
    }




    $product = Product::createNewProduct('new product name');


    and we need to execute this code on all clone sites, given that an exception is possible on one of them, in which case the record should not be added to any of the sites.

    For example: This is how it should look! The problem is that:

    beginTransaction();

    try {
    $product = Product::crateateNewProduct('new product name);
    commitTransaction();
    } catch (Exception $e) {
    rollbackTransaction();

    throw new Exception('clone-wide code execution failure');
    }




    1. exactly the same code must be executed simultaneously on all clone sites;
    2. the commitTransaction () function should not make a “real” commit until all clone sites “give the go-ahead”
    3. when you get into the rollbackTransaction () function on at least one of the clones, an exception must be thrown on all clones so that all sites “roll back”, even if they have no errors.


    For this:

    1. let the functions to support "distributed transactions" notify the state of the transaction. For example, a file with the line BEGIN / READY / COMMITED / ROLLBACK accessible from the outside, for example example1.com/transaction/status.txt
    2. let's make the commitTransaction () function before confirming the MySQL transaction “run through” all known clone sites and check that “everything is in order” and only in this case execute COMMIT. Otherwise, it would throw an exception;
    3. we will make the rollbackTransaction () function also save the status in the status.txt file so that other clone sites can learn about it and “roll back”


    The picture illustrates this:

    image

    Similarly, you can execute any code, for example, changing the status of a product or editing a card. You just need to find a way to pass 4code code, which must be executed "synchronously on all clones" and call eval ($ code).

    There is still a small problem - how to make sure that the code is executed [more or less] simultaneously on all sites. I solved this with nohup, but I think there are other ways.

    I would like to discuss all this with habrachelovekami.

    Also popular now: