Treci la conținut

Revenire

Nu generați o revenire doar din instantaneea de bază. Baza este strămoșul comun, nu neapărat starea live care va fi suprascrisă.

Nu generați o revenire doar din instantaneul de bază. „Base” este strămoșul comun, nu neapărat starea live care va fi suprascrisă.

Crearea unui plan de revenire

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'],
);
  • ID-ul planului de îmbinare,

  • ID-urile operațiilor selectate,

  • tabelele afectate,

  • operațiile inverse,

  • rândurile anterioare,

  • rândurile ulterioare așteptate,

  • metadatele,

  • un hash pentru revenire,

  • o versiune a schemei.

  • ID-ul planului de îmbinare,

  • ID-urile operațiilor selectate,

  • tabelele atinse,

  • operațiile inverse,

  • rândurile anterioare,

  • rândurile așteptate după operații,

  • metadate,

  • un hash de revenire,

  • o versiune a schemei.

Verificarea modificărilor

Verificarea modificărilor compară amprentele rândurilor, deci ordinea coloanelor nu contează.

PHP
use Merql\Rollback\RollbackDrift;

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

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

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

Verificarea modificărilor compară amprentele rândurilor, așadar ordinea coloanelor nu contează.

Aplicarea revenirii

Când nu există modificări, aplicați operațiile inverse.

PHP
use Merql\Rollback\RollbackPlanApplier;

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

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

Revenirea aplică un MergeResult obișnuit, creat din operații inverse. Acesta rulează pe aceeași cale tranzacțională de aplicare ca aplicarea obișnuită a îmbinărilor.

Serializare

Aplicațiile ar trebui să stocheze planul serializat împreună cu operația care a efectuat scrierea live și cu orice metadate de audit specifice gazdei.

PHP
use Merql\Rollback\RollbackPlanSerializer;

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

Aplicațiile ar trebui să stocheze planul serializat alături de operația care a efectuat scrierea live, împreună cu orice metadate de audit specifice gazdei.