Как да се справим с услуга без транзакция по време на транзакция?

Да предположим, че имам SQL транзакционна финансова система, но по време на транзакция тя извиква външна не-SQL услуга.

Как да се справите с напр. загуба на мощност, когато нямаме информация дали външното повикване е било успешно или не?

Нека си представим това в SQL база данни и биткойн портфейл, правещ транзакция.

  1. Стартирайте SQL транзакция
  2. Намалете сумата на потребителя в брой
  3. Изпратете пари в брой на потребителя някъде чрез биткойн портфейла
  4. Ангажирайте се

Загубата на захранване между стъпка 3 и 4 ще попречи на извършването на транзакция (няма намаляване на парите на потребителя), но всъщност ще изпрати нашите пари от портфейла.

Вторият сценарий е да се намалят парите на потребителя и да се ангажира, преди да се обади на външна услуга. Но когато настъпи загуба на захранване след повреда на външна услуга (всъщност не са изпратени) пари, ние не го правим, за да върнем средствата на потребителя след повреда на външната услуга (да предположим, че биткойн портфейлът не работи).

В момента намалявам парите и маркирам транзакцията като „в ход“ (и я ангажирам) преди повикване към външна услуга, след това, ако външната услуга отговори ОК, маркирам всичко като успешно завършено.

Но при загуба на захранване все още мога да остана в ситуация, че някоя транзакция след загуба на захранване е маркирана като „в процес“, парите са намалели, но трябва да проверя ръчно транзакциите в биткойн портфейл/блокчейн, ако парите наистина са били изпратени.

Има ли по-добър начин за управление на транзакции в тази ситуация? Възможно ли е да се реши по някакъв начин, без да е възможно да се провери в бъдеще дали нашето външно обаждане е било успешно или не? (като мога да проверя всички минали транзакции в блокчейн)


person Piotr Müller    schedule 18.06.2014    source източник


Отговори (1)


Добре дошли в прекрасния свят на разпределените транзакции! След като работи върху тях в продължение на много години на различни места (MS, Google и т.н.), Пат Хеланд стигна до заключението, че няма сребърен куршум и че най-доброто, което можете да направите, е да изберете „Eventual Съгласуваност“.

Започвате добре с флага „В ход“. Без да знам подробностите за отдалечената транзакция (т.е. през какви стъпки трябва да преминете, какви данни са налични при завършване на всяка), не мога да ви кажа как точно да го направите, така че ето някои общи неща.

Ако можете да получите идентификатор на транзакция от отдалечения сайт, преди транзакцията да бъде ангажирана, тогава, когато го получите, актуализирайте вашата локална база данни с този идентификатор на транзакция. Когато отдалечената транзакция приключи, актуализирайте флага „Завършено“ на вашата локална база данни.

Сега ще имате няколко възможни състояния. Само две се нуждаят от внимание:

  1. В ход е зададено, не е завършено, няма идентификатор на транзакция: трябва да се стартира и завърши транзакцията remnote
  2. В процес е зададено, не е завършено, ID на транзакция съществува: може да бъде ангажирано в отдалечен сайт; свържете се с него, за да проверите дали тази транзакция е завършена; ако не е завършен (или се върнете към първото състояние и направете всичко)

Това е очертание. Както казах, не знам тънкостите на това как се извършва биткойн транзакция, но се надявам, че ви дава представа.

person simon at rcl    schedule 18.06.2014