Ga naar de inhoud

Terugdraaien

Terugdraaiplannen beschrijven hoe u geselecteerde samenvoegingsbewerkingen ongedaan maakt nadat ze zijn toegepast. Ze worden vóór het toepassen opgebouwd met de exacte live rijen die vlak vóór het schrijven bestaan.

Genereer een rollback niet alleen op basis van de basissnapshot. De basis is de gemeenschappelijke voorouder, niet noodzakelijk de live status die wordt overschreven.

Een terugdraaiplan opbouwen

PHP
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'],
);

Het plan bevat:

  • de ID van het samenvoegingsplan,
  • geselecteerde bewerkings-ID's,
  • geraakte tabellen,
  • omgekeerde bewerkingen,
  • rijen van vóór de wijziging,
  • verwachte rijen van na de wijziging,
  • metadata,
  • een rollback-hash,
  • een schemaversie.

Afwijkingen controleren

Vergelijk vóór het terugdraaien de huidige live rijen met de verwachte rijen van na de wijziging in het terugdraaiplan. Als een rij sinds de promotie is gewijzigd, wordt de bewerking standaard afgebroken.

PHP
use Merql\Rollback\RollbackDrift;

$currentRows = [
    $operationId => $currentLiveRow,
];

$drifted = (new RollbackDrift())->driftedOperationIds($rollback, $currentRows);

if ($drifted !== []) {
    throw new RuntimeException('Rollback drifted: ' . implode(', ', $drifted));
}

De controle op afwijkingen vergelijkt rijvingerafdrukken, dus de kolomvolgorde maakt niet uit.

Terugdraaien toepassen

Pas de omgekeerde bewerkingen toe als er geen afwijkingen zijn.

PHP
use Merql\Rollback\RollbackPlanApplier;

$applied = (new RollbackPlanApplier($connection))->apply($rollback);

if ($applied->hasErrors()) {
    foreach ($applied->errors() as $error) {
        echo $error . "\n";
    }
}

Terugdraaien past een normaal MergeResult toe dat is opgebouwd uit omgekeerde bewerkingen. Dit verloopt via hetzelfde transactionele pad van de applier als een gewone samenvoeging.

Serialisatie

Bewaar terugdraaiplannen voordat u de voorwaartse samenvoeging toepast. Dat artefact vormt de duurzame basis voor later terugdraaien.

PHP
use Merql\Rollback\RollbackPlanSerializer;

$json = RollbackPlanSerializer::toJson($rollback);
$restored = RollbackPlanSerializer::fromJson($json);

Applicaties moeten het geserialiseerde plan opslaan bij de bewerking die de live wijziging uitvoerde, samen met eventuele auditmetadata die specifiek is voor de host.