Atšaukimas
Atšaukimo planuose aprašoma, kaip atšaukti pasirinktas sujungimo operacijas jas pritaikius. Jie sudaromi prieš pritaikymą, naudojant tikslias tiesiogines eilutes, kurios egzistuoja prieš pat įrašymą.
Nesudarykite atšaukimo plano vien iš bazinės momentinės kopijos. Bazinė versija yra bendras protėvis, o ne būtinai tiesioginė būsena, kuri bus perrašyta.
Atšaukimo plano sudarymas
use Merql\Plan\ChangeGroupSelection;
use Merql\Rollback\RollbackPlanBuilder;
use Merql\Snapshot\SnapshotStore;
$selection = ChangeGroupSelection::fromIds([$plan->changeGroups[0]->id]);
$operationSelection = $selection->toOperationSelection($plan);
$expectedLive = SnapshotStore::load($plan->theirsSnapshot);
$liveBeforeRows = [];
foreach ($plan->operations as $operation) {
if (!$operationSelection->contains($operation->id)) {
continue;
}
$liveBeforeRows[$operation->id] = $expectedLive
->getTable($operation->table)
?->getRow($operation->rowKey);
}
$rollback = (new RollbackPlanBuilder())->build(
'rollback-1',
$plan,
$operationSelection,
$liveBeforeRows,
metadata: ['promotion_id' => 'promotion-1'],
);
Plane saugoma:
- sujungimo plano ID,
- pasirinktų operacijų ID,
- paveiktos lentelės,
- atvirkštinės operacijos,
- eilutės prieš pakeitimą,
- numatytos eilutės po pakeitimo,
- metaduomenys,
- atšaukimo maiša,
- schemos versija.
Neatitikimų patikra
Prieš pritaikydami atšaukimą, palyginkite dabartines tiesiogines eilutes su atšaukimo plane numatytomis eilutėmis po pakeitimo. Jei po perkėlimo kuri nors eilutė pasikeitė, pagal numatytąją nuostatą nutraukite operaciją.
use Merql\Rollback\RollbackDrift;
$currentRows = [
$operationId => $currentLiveRow,
];
$drifted = (new RollbackDrift())->driftedOperationIds($rollback, $currentRows);
if ($drifted !== []) {
throw new RuntimeException('Rollback drifted: ' . implode(', ', $drifted));
}
Neatitikimų patikra lygina eilučių kontrolines žymas, todėl stulpelių tvarka nesvarbi.
Atšaukimo pritaikymas
Jei neatitikimų nėra, pritaikykite atvirkštines operacijas.
use Merql\Rollback\RollbackPlanApplier;
$applied = (new RollbackPlanApplier($connection))->apply($rollback);
if ($applied->hasErrors()) {
foreach ($applied->errors() as $error) {
echo $error . "\n";
}
}
Atšaukimas pritaiko įprastą MergeResult, sudarytą iš atvirkštinių operacijų. Jis vykdomas tuo pačiu operacijų taikytojo operacijų su transakcijomis keliu kaip įprastas sujungimo pritaikymas.
Serializavimas
Prieš pritaikydami sujungimą į priekį, išsaugokite atšaukimo planus. Šis artefaktas yra patikimas pagrindas vėlesniam atšaukimui.
use Merql\Rollback\RollbackPlanSerializer;
$json = RollbackPlanSerializer::toJson($rollback);
$restored = RollbackPlanSerializer::fromJson($json);
Programos turėtų išsaugoti serializuotą planą kartu su operacija, kuri atliko įrašymą į tiesioginę duomenų bazę, ir visais konkrečiai pagrindinei programai skirtais audito metaduomenimis.