Обработка ошибок базы данных: что делать, если вам необходимо позвонить в службу извне и транзакция не выполняется - PullRequest
0 голосов
/ 23 октября 2009

Мы все знаем, что мы всегда можем заключить наш вызов базы данных в транзакцию (с или без надлежащего ORM) в такую ​​форму:

$con = Propel::getConnection(EventPeer::DATABASE_NAME);
try {
    $con->begin();
    // do your update, save, delete or whatever here.
    $con->commit();
} catch (PropelException $e) {
    $con->rollback();
    throw $e;
}

Этот способ гарантирует, что в случае сбоя транзакции база данных будет восстановлена ​​в правильном состоянии.

Но проблема в том, что, скажем, когда я делаю транзакцию, в дополнение к этой транзакции мне нужно обновить другую базу данных (например, когда я обновляю запись в столбце в databaseA, другую запись в столбце в база данныхB должна быть обновлена). Как справиться с этим делом?

Допустим, это мой код, у меня есть три базы данных, которые необходимо обновить (dbA, dbB, dbc):

$con = Propel::getConnection("dbA");
try {
    $con->begin();
    // update to dbA
    // update to dbB
    //update to dbc
    $con->commit();
} catch (PropelException $e) {
    $con->rollback();
    throw $e;
}

Если сбой dbc, я могу откатить dbA, но не могу откатить dbb.

Я думаю, что эта проблема должна быть независимой от базы данных. И поскольку я использую ORM, он также должен быть независимым от ORM.

Обновление: некоторые транзакции базы данных обернуты в ORM, некоторые используют открытый PDO, oledb (или любой другой язык базы данных, предоставляемый вызовами). Поэтому мое решение должно позаботиться об этом.

Есть идеи?

Ответы [ 3 ]

1 голос
/ 23 октября 2009

Во-первых, некоторые базы данных поддерживают протоколы распределенных транзакций, которые позволят всем dbA, dbB и dbC одновременно участвовать в одной транзакции. Если у вас есть, используйте это:)

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

0 голосов
/ 23 октября 2009

Большинство СУБД поддерживают распределенные транзакции. Например, MS SQL Server использует Coididator распределенных транзакций (DTC), сервис, для включения распределенных транзакций .

0 голосов
/ 23 октября 2009

Вам нужна СУБД, которая поддерживает Распределенные транзакции . Они делают именно то, что вам нужно: они обеспечивают семантику начала / принятия / отката в нескольких системах.

Например, Enterprise Java Beans и Microsoft Transaction Server поддерживают распределенные транзакции.

Если «вызов снаружи» не относится к базе данных, он становится еще сложнее. Вы можете попытаться эмулировать транзакции, но некоторые вещи трудно откатить (операции с файловой системой) или невозможно (отправка данных на сервер). Так что это будет зависеть от конкретной проблемы.

...