Обрабатывать транзакции для двух независимых источников данных как один - PullRequest
1 голос
/ 29 октября 2009

У меня есть два источника данных: старый (веб-сервис) и база данных. Теперь, когда я обрабатываю запрос, я внес изменения в оба. В случае ошибки я хочу откатить оба.

try
{
  legacy.Begin(); db.Begin();
  legacy.MakeChanges(); db.MakeChanges();
}
except (Exception)
{
  legacy.Rollback(); db.Rollback();
}

Проблема в том, что, если устаревшие скины во время отката (т.е. ошибка сети)? db.Rollback () не будет выполнен. И наоборот. Решение, которое я вижу:

legacy.Begin(); 
try
{
  db.Begin();
  try
  {
      legacy.MakeChanges(); db.MakeChanges();
  }
  except (Exception)
  {
    db.Rollback();
    throw;
  }
}
except (Exception)
{
  legacy.Rollback(); 
  throw;
}

Это приемлемо? Есть ли лучшее решение?

1 Ответ

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

Вы эффективно выполняете свои собственные транзакции двухфазной фиксации. Полностью надежное решение требует сотрудничества с обоих ресурсов и обычно лучше всего использовать менеджер транзакций с поддержкой 2PC.

Основная проблема заключается в том, что у вас нет защиты от сбоя собственного приложения (он играет роль менеджера транзакций) и, следовательно, нет гарантии, что вы сможете откатить это наследие. Рассмотрим сбой вашего приложения как раз в тот момент, когда оно собиралось вызвать legcacy.Rollbock (). Теперь у вас нет записи о том, что вы были в середине «транзакции», и поэтому, когда ваше приложение возвращается, у вас нет причин идти и выполнять этот откат.

Возможные подходы:

1). Используйте true 2PC, это возможно только в том случае, если ваш WebSerice имеет транзакционные возможности (технически возможно, но практически маловероятно).

2). Терпеть риск некоторых несоответствий. Многие системы фактически делают это непреднамеренно,

3). Сделайте попытку восстановления, к которому вы стремитесь, но примите к сведению, что оно может потерпеть неудачу. Добавьте некоторую форму контрольного журнала, которая позволяет обнаруживать неопределенные результаты и, следовательно, позволяет вручную исправлять ошибки позже. Таким образом, вы могли бы добавить какую-то контрольную запись, которая позволила бы выявлять ошибочные действия. Это можно рассматривать как своего рода очень ручной подход 2PC.

...