Gå til indhold

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

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

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.

PHP
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.

PHP
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.

PHP
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.