Vrácení změn
Plány vrácení popisují, jak zrušit vybrané operace sloučení poté, co byly použity. Vytvářejí se před použitím, a to na základě přesných živých řádků, které existují bezprostředně před zápisem.
Nevytvářejte plán vrácení pouze ze základního snímku. Základ je společný předek, nikoli nutně aktuální stav, který se přepisuje.
Sestavení plánu vrácení
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'],
);
Plán ukládá:
- ID plánu sloučení,
- ID vybraných operací,
- dotčené tabulky,
- opačné operace,
- původní řádky,
- očekávané výsledné řádky,
- metadata,
- kontrolní součet vrácení,
- verzi schématu.
Kontrola odchylek
Před použitím vrácení porovnejte aktuální živé řádky s očekávanými výslednými řádky plánu. Pokud se od propagace změnil kterýkoli řádek, standardně se operace přeruší.
use Merql\Rollback\RollbackDrift;
$currentRows = [
$operationId => $currentLiveRow,
];
$drifted = (new RollbackDrift())->driftedOperationIds($rollback, $currentRows);
if ($drifted !== []) {
throw new RuntimeException('Rollback drifted: ' . implode(', ', $drifted));
}
Kontrola odchylek porovnává otisky řádků, takže na pořadí sloupců nezáleží.
Použití vrácení změn
Pokud nejsou žádné odchylky, použijte opačné operace.
use Merql\Rollback\RollbackPlanApplier;
$applied = (new RollbackPlanApplier($connection))->apply($rollback);
if ($applied->hasErrors()) {
foreach ($applied->errors() as $error) {
echo $error . "\n";
}
}
Vrácení změn použije běžný MergeResult vytvořený z opačných operací. Probíhá stejnou transakční cestou aplikátoru jako běžné použití sloučení.
Serializace
Před použitím sloučení uložte plán vrácení. Tento artefakt je trvalým základem pro pozdější vrácení změn.
use Merql\Rollback\RollbackPlanSerializer;
$json = RollbackPlanSerializer::toJson($rollback);
$restored = RollbackPlanSerializer::fromJson($json);
Aplikace by měly serializovaný plán ukládat spolu s operací, která provedla zápis do živé databáze, a s případnými auditními metadaty specifickými pro hostitelské prostředí.