Exemple #1
0
function deleteOrder($id, $ownerId)
{
    $orderConnection = mappedConnection('orders');
    $userConnection = mappedConnection('users');
    $price = findOrderPriceById($orderConnection, $id, $ownerId);
    if (!$price) {
        return false;
    }
    $sqlOrders = 'UPDATE orders SET deleted = TRUE WHERE id = ' . (int) $id . ' AND done_by IS NULL AND deleted IS FALSE;';
    $sqlUsers = 'UPDATE users SET cash = cash + ' . $price . ' WHERE id = ' . $ownerId . ';';
    if ($orderConnection === $userConnection) {
        mysqli_begin_transaction($orderConnection);
        mysqli_query($orderConnection, $sqlOrders);
        if ($result = (bool) mysqli_affected_rows($orderConnection)) {
            mysqli_query($orderConnection, $sqlUsers);
            mysqli_commit($orderConnection);
            return true;
        }
        mysqli_rollback($orderConnection);
        return false;
    } else {
        $result = false;
        $uuid = uniqid('', false);
        $transactionOrder = '\'' . $uuid . '\', \'oi\'';
        $transactionUser = '******'' . $uuid . '\', \'ui\'';
        mysqli_query($userConnection, 'DO GET_LOCK(\'' . $uuid . '-u\', 1);');
        mysqli_query($orderConnection, 'DO GET_LOCK(\'' . $uuid . '-o\', 1);');
        // стартуем транзакцию на базе с заказами
        mysqli_query($orderConnection, 'XA START ' . $transactionOrder . ';');
        // удаляем заказ
        mysqli_query($orderConnection, $sqlOrders);
        $completed = mysqli_affected_rows($orderConnection);
        mysqli_query($orderConnection, 'XA END ' . $transactionOrder . ';');
        // если получилось удалить
        if ($completed) {
            mysqli_query($userConnection, 'XA START ' . $transactionUser . ';');
            mysqli_query($userConnection, $sqlUsers);
            mysqli_query($userConnection, 'XA END ' . $transactionUser . ';');
            // подготавиливаем обе транзакции
            if (mysqli_query($orderConnection, 'XA PREPARE ' . $transactionOrder . ';')) {
                if (mysqli_query($userConnection, 'XA PREPARE ' . $transactionUser . ';')) {
                    // пытаемся закоммитить удаление заказа
                    if (mysqli_query($orderConnection, 'XA COMMIT ' . $transactionOrder . ';')) {
                        // плюсуем деньги, если в этот момет БД упала, то коммитим при поднятии.
                        mysqli_query($userConnection, 'XA COMMIT ' . $transactionUser . ';');
                        $result = true;
                    } else {
                        // если что-то пошло не так, откатываем
                        mysqli_query($userConnection, 'XA ROLLBACK ' . $transactionUser . ';');
                    }
                } else {
                    mysqli_query($orderConnection, 'XA ROLLBACK ' . $transactionOrder . ';');
                }
            } else {
                mysqli_query($userConnection, 'XA ROLLBACK ' . $transactionUser . ';');
            }
        } else {
            // коммитим, изменений все равно нет.
            mysqli_query($orderConnection, 'XA COMMIT ' . $transactionOrder . ' ONE PHASE;');
        }
        mysqli_query($userConnection, 'DO RELEASE_LOCK(\'' . $uuid . '-u\');');
        mysqli_query($orderConnection, 'DO RELEASE_LOCK(\'' . $uuid . '-o\');');
        return $result;
    }
}
Exemple #2
0
function completeOrder($id, $userId)
{
    $id = (int) $id;
    $userId = (int) $userId;
    $userConnection = mappedConnection('users');
    $orderConnection = mappedConnection('orders');
    $price = findOrderPriceById($orderConnection, $id, $userId);
    if (!$price) {
        return false;
    }
    $commission = calculateCommission($price);
    $reward = $price - $commission;
    $sqlOrders = 'UPDATE orders SET done_by = ' . $userId . ', commission = ' . $commission . ' WHERE id = ' . $id . ' AND done_by IS NULL AND orders.deleted IS FALSE;';
    $sqlUsers = 'UPDATE users SET cash = cash + ' . $reward . ' WHERE id = ' . $userId . ';';
    if ($userConnection === $orderConnection) {
        mysqli_begin_transaction($orderConnection);
        mysqli_query($orderConnection, $sqlOrders);
        if ($result = (bool) mysqli_affected_rows($orderConnection)) {
            mysqli_query($orderConnection, $sqlUsers);
            mysqli_commit($orderConnection);
            return true;
        }
        mysqli_rollback($orderConnection);
        return false;
    } else {
        $uuid = uniqid('', false);
        // Лочим uuid, что бы скрипт поднятия оторваных транзакций не мешал ;)
        mysqli_query($userConnection, 'DO GET_LOCK(\'' . $uuid . '-u\', 1);');
        mysqli_query($orderConnection, 'DO GET_LOCK(\'' . $uuid . '-o\', 1);');
        $transactionOrder = '\'' . $uuid . '\', \'oc\'';
        $transactionUser = '******'' . $uuid . '\', \'uc\'';
        // стартуем транзакцию на базе с заказами
        mysqli_query($orderConnection, 'XA START ' . $transactionOrder . ';');
        // помечаем заказ выполненым
        mysqli_query($orderConnection, $sqlOrders);
        $completed = mysqli_affected_rows($orderConnection);
        mysqli_query($orderConnection, 'XA END ' . $transactionOrder . ';');
        $result = false;
        // если получилось пометить как выполненое
        if ($completed) {
            mysqli_query($userConnection, 'XA START ' . $transactionUser . ';');
            mysqli_query($userConnection, $sqlUsers);
            mysqli_query($userConnection, 'XA END ' . $transactionUser . ';');
            // подготавиливаем обе транзакции
            if (mysqli_query($orderConnection, 'XA PREPARE ' . $transactionOrder . ';')) {
                if (mysqli_query($userConnection, 'XA PREPARE ' . $transactionUser . ';')) {
                    // пытаемся закоммитить изменения заказа
                    if (mysqli_query($orderConnection, 'XA COMMIT ' . $transactionOrder . ';')) {
                        // плюсуем деньги, если в этот момет БД упала, то коммитим при поднятии.
                        mysqli_query($userConnection, 'XA COMMIT ' . $transactionUser . ';');
                        $result = true;
                    } else {
                        // если что-то пошло не так, пробуем откатить
                        mysqli_query($userConnection, 'XA ROLLBACK ' . $transactionUser . ';');
                    }
                } else {
                    mysqli_query($orderConnection, 'XA ROLLBACK ' . $transactionOrder . ';');
                }
            } else {
                mysqli_query($userConnection, 'XA ROLLBACK ' . $transactionUser . ';');
            }
        } else {
            // коммитим, изменений все равно нет.
            mysqli_query($orderConnection, 'XA COMMIT ' . $transactionOrder . ' ONE PHASE;');
        }
        mysqli_query($userConnection, 'DO RELEASE_LOCK(\'' . $uuid . '-u\');');
        mysqli_query($orderConnection, 'DO RELEASE_LOCK(\'' . $uuid . '-o\');');
        return $result;
    }
}