мета-данные страницы
Различия
Здесь показаны различия между двумя версиями данной страницы.
Предыдущая версия справа и слева Предыдущая версия Следующая версия | Предыдущая версия | ||
agbis_idempotency [31.05.2022 10:33] Anatoly |
agbis_idempotency [31.05.2022 10:44] (текущий) |
||
---|---|---|---|
Строка 3: | Строка 3: | ||
Можно ознакомится со статьей от Яндекс: [[https://habr.com/ru/company/yandex/blog/442762/]] | Можно ознакомится со статьей от Яндекс: [[https://habr.com/ru/company/yandex/blog/442762/]] | ||
---- | ---- | ||
- | [[#Обработка в агенте|Обработка в агенте]] | + | [[#Введение|Введение]]\\ |
- | [[#Обработка на клиенте|Обработка на клиенте]] | + | [[#Обработка в агенте|Обработка в агенте]]\\ |
- | [[#Пример МП Courier|Пример МП Courier]] | + | [[#Обработка на клиенте|Обработка на клиенте]]\\ |
- | [[#Пример Бонусы Онлайн|Пример Бонусы Онлайн]] | + | [[#Пример МП Courier|Пример МП Courier]]\\ |
+ | [[#Пример Бонусы Онлайн|Пример Бонусы Онлайн]]\\ | ||
---- | ---- | ||
- | ===== 1. Пишущая транзакция (на сервере) ===== | ||
+ | ===== Введение ===== | ||
+ | |||
+ | Идемпотентность - это операция, которая при многократном вызове возвращает один и тот же результат.\\ | ||
+ | Или метод HTTP является идемпотентным, если повторный идентичный запрос, сделанный один или несколько раз подряд, имеет один и тот же эффект, не изменяющий состояние сервера. | ||
+ | ---- | ||
===== Обработка в агенте ===== | ===== Обработка в агенте ===== | ||
Строка 98: | Строка 103: | ||
---- | ---- | ||
==== Клиент ==== | ==== Клиент ==== | ||
- | - Организовать уникальность запроса | + | - Организовать уникальность запроса; |
- | - Обработку ErrorCode = 5 | + | - Обработку код Error = 5. |
---- | ---- | ||
Строка 106: | Строка 111: | ||
===== Пример МП Courier ===== | ===== Пример МП Courier ===== | ||
- | <code pascal> | + | <sxh Delphi> |
... | ... | ||
... | ... | ||
var | var | ||
- | PayIdempotency: string;/ /'Переменная сохраняет состояние текущей транзакции /запрос(dor_id, debet) + ответ(JSON)/' | + | PayIdempotency: string;//'Переменная сохраняет состояние текущей транзакции /запрос(dor_id, debet) + ответ(JSON)/' |
... | ... | ||
... | ... | ||
- | JSONAnswer := KassaFiscalRegistar.PrintFiscalCheck(JSONResultObj); / /'Печать чека' | + | JSONAnswer := KassaFiscalRegistar.PrintFiscalCheck(JSONResultObj); //'Печать чека' |
... | ... | ||
except | except | ||
on E: Exception do | on E: Exception do | ||
begin | begin | ||
- | PayIdempotency := ''; / /'Если ошибка при печати - обнуляем текущую транзакцию' | + | PayIdempotency := ''; //'Если ошибка при печати - обнуляем текущую транзакцию' |
... | ... | ||
Строка 126: | Строка 131: | ||
procedure TmoneyPayFramePanel.OnShow(curVisible: TuniFramePanel); | procedure TmoneyPayFramePanel.OnShow(curVisible: TuniFramePanel); | ||
begin | begin | ||
- | PayIdempotency := '';/ / 'При входе обнуление предыдущей транзакции' | + | PayIdempotency := '';// 'При входе обнуление предыдущей транзакции' |
... | ... | ||
Строка 132: | Строка 137: | ||
ClnDM.GetFiscalCheck(sJSON, | ClnDM.GetFiscalCheck(sJSON, | ||
procedure (AJObject: TJSONObject) | procedure (AJObject: TJSONObject) | ||
- | var CurrentPayIdempotency: string; / /'Текущая транзакция' | + | var CurrentPayIdempotency: string; //'Текущая транзакция' |
begin | begin | ||
CurrentPayIdempotency := THashMD5.GetHashString(sJSON + '=' + AJObject.ToString); | CurrentPayIdempotency := THashMD5.GetHashString(sJSON + '=' + AJObject.ToString); | ||
- | if PayIdempotency = CurrentPayIdempotency then / /'Текущую сравниваем с запомненой' | + | if PayIdempotency = CurrentPayIdempotency then //'Текущую сравниваем с запомненой' |
begin | begin | ||
- | / / 'Ничего не делаем если транзакция все еще ТА ЖЕ' | + | // 'Ничего не делаем если транзакция все еще ТА ЖЕ' |
WriteLog("TmoneyPayFramePanel.WorkOfPay PayIdempotency = CurrentPayIdempotency Abort"); | WriteLog("TmoneyPayFramePanel.WorkOfPay PayIdempotency = CurrentPayIdempotency Abort"); | ||
end | end | ||
else | else | ||
begin | begin | ||
- | / /'Транзакция другая - выпонить оплату' | + | //'Транзакция другая - выпонить оплату' |
PayIdempotency := CurrentPayIdempotency; | PayIdempotency := CurrentPayIdempotency; | ||
AnswerFromWeb('GetFiscalCheck', '', 0, AJObject); | AnswerFromWeb('GetFiscalCheck', '', 0, AJObject); | ||
Строка 150: | Строка 155: | ||
... | ... | ||
- | </code> | + | </sxh> |
---- | ---- | ||
===== Пример Бонусы Онлайн ===== | ===== Пример Бонусы Онлайн ===== | ||
Строка 156: | Строка 161: | ||
function BonusOnlineSend(const data: string; out j: TJsonObject): Boolean; | function BonusOnlineSend(const data: string; out j: TJsonObject): Boolean; | ||
var | var | ||
- | codeApi, res, Idempotency_GUID: string; | + | ... |
+ | Idempotency_GUID: string; // Переменная сохраняет состояние текущей транзакции | ||
ReconIdempotencyCount: integer; | ReconIdempotencyCount: integer; | ||
json: TJsonValue; | json: TJsonValue; | ||
Строка 162: | Строка 168: | ||
begin | begin | ||
Result := False; | Result := False; | ||
- | Idempotency_GUID := ''; | + | Idempotency_GUID := ''; // При входе обнуление предыдущей транзакции |
try | try | ||
- | CreateIdempotency_GUID(Idempotency_GUID); | + | CreateIdempotency_GUID(Idempotency_GUID); // Текущая транзакция |
ReconIdempotencyCount := 0; | ReconIdempotencyCount := 0; | ||
json := nil; | json := nil; | ||
Строка 182: | Строка 188: | ||
... | ... | ||
else | else | ||
- | if codeApi = '5' then | + | if codeApi = '5' then // Действия при 5 коде |
begin | begin | ||
- | if ReconIdempotencyCount < 2 then | + | if ReconIdempotencyCount < 2 then // Проверяем количество провторов |
begin | begin | ||
WriteLog('errorResult = 5, повторный запрос'); | WriteLog('errorResult = 5, повторный запрос'); | ||
Sleep(500); | Sleep(500); | ||
- | inc(ReconIdempotencyCount); | + | inc(ReconIdempotencyCount); |
- | Continue; | + | Continue; // Пробуем еще раз |
end | end | ||
else | else | ||
begin | begin | ||
- | ReconIdempotencyCount := 0; | + | ReconIdempotencyCount := 0; // Обнулим счетчик и сообщим об ошибке |
WriteLog(_UTFDecode(JSON_O.Get('Msg').JsonValue.Value)); | WriteLog(_UTFDecode(JSON_O.Get('Msg').JsonValue.Value)); | ||
Строка 211: | Строка 217: | ||
if Assigned(json) then | if Assigned(json) then | ||
FreeAndNil(json); | FreeAndNil(json); | ||
- | Idempotency_GUID := ''; | + | Idempotency_GUID := ''; |
end; | end; | ||
end; | end; | ||
Строка 232: | Строка 238: | ||
try | try | ||
if Idempotency_GUID <> '' then // идентификатор запроса | if Idempotency_GUID <> '' then // идентификатор запроса | ||
- | Headers.Add('XIdempotency-GUID: ' + Idempotency_GUID); | + | Headers.Add('XIdempotency-GUID: ' + Idempotency_GUID); // Передаем в запросе |
| | ||
Headers.Add('Accept-Encoding: deflate'); | Headers.Add('Accept-Encoding: deflate'); |