Rose debug info
---------------

SOA и транзакций мучений пост

Имеем сервис-ориентированное приложение. На сервисе AAA вызывается метод, который должен сделать 1 запись в БД (отправить запрос на сервис БД), отправить запрос на два других сервиса, которые в свою очередь тоже должны сделать по 1 записи в БД (отправить запросы на сервис БД) каждый.

Как сделать так, чтобы если хотя бы один из сервисов не смог сделать свою запись в БД, другие записи тоже откатились бы?

Отправлять на сервис БД uniqid транзакции, сервис БД должен будет дождаться все запросы с таким uniqid, затем сотворить что-то вроде:

$db = self::db();
$q['1111-1111-111'] =  "UPDATE balance SET total = total - 100 WHERE account_id=1;UPDATE balance SET total = total + 100 WHERE account_id=2;";
$db->beginTransaction();
try
{
$db->exec($q['1111-1111-111']);
$query = $db->commit();
}
catch(Exception $e)
{
$db->rollBack();
}

А если каждый последующий запрос связан с результатом предыдущего? Скажем, нужно в сервис BBB передавать ID сущности добавленной сервисом AAA? Обломинго.

В каждом сервисе реализовать обратную связь, и в случае неудачной операции с БД, сообщать сервису, вызвавшему метод, что операция прошла неудачно и надо бы все предыдущие записи в бд снести подчистую?

Или. В сервисе ААА генерить uniqid транзакции, сообщать его дочерним сервисам, и сервису БД, и сервис БД сам, в случае неудачной операции в БД должен удалить все записи с таким uniqid.

А если это не INSERT, а UPDATE или DELETE? Хранить где-то бекап обновляемой/удаляемой сущности?..

1 комментарий
Дмитрий Бергштейн 2011

А всё почему?
Потому что транзакции делал джавист, билять.

И они нихуя не stateful.

Думаю, идеально будет передавать Call UID, сверху донизу (почти второй вариант).