Как обнаружить, что транзакция уже началась? - PullRequest
27 голосов
/ 26 ноября 2008

Я использую Zend_Db для вставки некоторых данных в транзакцию. Моя функция запускает транзакцию, а затем вызывает другой метод, который также пытается запустить транзакцию и, конечно, не удается (я использую MySQL5). Итак, вопрос - как я могу обнаружить, что транзакция уже была начата? Вот пример кода:

       try {
                    Zend_Registry::get('database')->beginTransaction();

                    $totals = self::calculateTotals($Cart);
                    $PaymentInstrument = new PaymentInstrument;
                    $PaymentInstrument->create();
                    $PaymentInstrument->validate();
                    $PaymentInstrument->save();

                    Zend_Registry::get('database')->commit();
                    return true;

            } catch(Zend_Exception $e) {
                    Bootstrap::$Log->err($e->getMessage());
                    Zend_Registry::get('database')->rollBack();
                    return false;
            }

Внутри PaymentInstrument :: create есть еще одна инструкция beginTransaction, которая создает исключение, которое говорит о том, что транзакция уже была начата.

Ответы [ 11 ]

0 голосов
/ 15 июля 2013

В PHP с веб-интерфейсом сценарии почти всегда вызываются во время одного веб-запроса. В этом случае вы действительно хотели бы начать транзакцию и зафиксировать ее непосредственно перед завершением сценария. Если что-то пойдет не так, бросьте исключение и откатите все обратно. Как это:

wrapper.php:

try {
   // start transaction
   include("your_script.php");
   // commit transaction
} catch (RollbackException $e) {
   // roll back transaction
}

Ситуация с шардингом становится немного сложнее, когда вы можете открывать несколько соединений. Вы должны добавить их в список соединений, где транзакции должны быть зафиксированы или откатаны в конце скрипта. Однако следует понимать, что в случае шардинга, если у вас нет глобального мьютекса в транзакциях, вы не сможете легко добиться истинной изоляции или атомарности параллельных транзакций, поскольку другой сценарий может передавать свои транзакции шардам во время фиксации ваша. Тем не менее, вы можете проверить распределенные транзакции MySQL .

...