Pāriet uz saturu

Atcelšana

Atcelšanas plāni apraksta, kā atsaukt atlasītās apvienošanas darbības pēc to izpildes. Tos izveido pirms izpildes, izmantojot precīzus tiešsaistes datus par rindām tieši pirms ierakstīšanas.

Neģenerējiet atcelšanu, balstoties tikai uz bāzes momentuzņēmumu. Bāze ir kopīgais sencis, nevis obligāti tiešsaistes stāvoklis, kas tiek pārrakstīts.

Atcelšanas plāna izveide

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

Plānā tiek saglabāts:

  • apvienošanas plāna ID,
  • atlasīto darbību ID,
  • skartās tabulas,
  • pretējās darbības,
  • iepriekšējās rindas,
  • paredzamās rindas pēc darbībām,
  • metadati,
  • atcelšanas jaucējvērtība,
  • shēmas versija.

Izmaiņu pārbaude

Pirms atcelšanas izpildes salīdziniet pašreizējās tiešsaistes rindas ar atcelšanas plānā paredzētajām rindām pēc darbībām. Ja kāda rinda kopš pārnešanas ir mainījusies, pēc noklusējuma darbība tiek pārtraukta.

PHP
use Merql\Rollback\RollbackDrift;

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

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

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

Izmaiņu pārbaudē salīdzina rindu pirkstu nospiedumus, tāpēc kolonnu secībai nav nozīmes.

Atcelšanas izpilde

Ja izmaiņu nav, izpildiet pretējās darbības.

PHP
use Merql\Rollback\RollbackPlanApplier;

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

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

Atcelšana lieto parastu MergeResult, kas izveidots no pretējām darbībām. Tā tiek izpildīta tajā pašā transakciju apstrādes ceļā, ko izmanto parastai apvienošanas izpildei.

Serializēšana

Saglabājiet atcelšanas plānus pirms apvienošanas sākotnējo darbību izpildes. Šis artefakts būs droši glabājamais pamats vēlākai atcelšanai.

PHP
use Merql\Rollback\RollbackPlanSerializer;

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

Lietotnēm vajadzētu glabāt serializēto plānu kopā ar darbību, kas veica ierakstīšanu tiešsaistes datubāzē, kā arī ar resursdatoram specifiskiem audita metadatiem.