Tilbagerulning
Tilbagerulningsplaner beskriver, hvordan valgte sammenfletningsoperationer fortrydes, efter at de er blevet anvendt. De opbygges før anvendelsen ud fra de nøjagtige live-rækker, der findes umiddelbart før skrivningen.
Generer ikke tilbagerulning alene ud fra basesnapshot. Base er den fælles forfader, ikke nødvendigvis den live-tilstand, der overskrives.
Opret en tilbagerulningsplan
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'],
);
Planen gemmer:
- ID for sammenfletningsplanen,
- ID'er for valgte operationer,
- berørte tabeller,
- inverse operationer,
- rækker før ændringen,
- forventede rækker efter ændringen,
- metadata,
- et tilbagerulningshash,
- en skemaversion.
Afvigelseskontrol
Før du anvender tilbagerulning, skal du sammenligne de aktuelle live-rækker med de forventede rækker efter planen for tilbagerulning. Hvis en række er ændret siden promoveringen, skal du som standard afbryde.
use Merql\Rollback\RollbackDrift;
$currentRows = [
$operationId => $currentLiveRow,
];
$drifted = (new RollbackDrift())->driftedOperationIds($rollback, $currentRows);
if ($drifted !== []) {
throw new RuntimeException('Rollback drifted: ' . implode(', ', $drifted));
}
Afvigelseskontrollen sammenligner rækkefingeraftryk, så kolonnernes rækkefølge er uden betydning.
Anvend tilbagerulning
Når der ikke er afvigelser, skal du anvende de inverse handlinger.
use Merql\Rollback\RollbackPlanApplier;
$applied = (new RollbackPlanApplier($connection))->apply($rollback);
if ($applied->hasErrors()) {
foreach ($applied->errors() as $error) {
echo $error . "\n";
}
}
Tilbagerulning anvender en normal MergeResult, der er bygget af inverse handlinger. Den kører gennem samme transaktionelle anvenderforløb som almindelig fletningsanvendelse.
Serialisering
Gem planer for tilbagerulning, før du anvender den fremadrettede fletning. Dette artefakt er det varige grundlag for senere tilbagerulning.
use Merql\Rollback\RollbackPlanSerializer;
$json = RollbackPlanSerializer::toJson($rollback);
$restored = RollbackPlanSerializer::fromJson($json);
Programmer bør gemme den serialiserede plan sammen med den handling, der udførte live-skrivningen, samt eventuelle værtsspecifikke revisionsmetadata.