Saltar al contenido

Reversión

Los planes de reversión describen cómo deshacer las operaciones de combinación seleccionadas después de aplicarlas. Se crean antes de la aplicación, a partir de las filas en vivo exactas que existen justo antes de la escritura.

No genere la reversión a partir de la instantánea base únicamente. La base es el antecesor común, pero no necesariamente el estado en vivo que se sobrescribirá.

Crear un plan de reversión

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

El plan almacena:

  • el ID del plan de combinación,
  • los ID de las operaciones seleccionadas,
  • las tablas afectadas,
  • las operaciones inversas,
  • las filas anteriores,
  • las filas posteriores esperadas,
  • los metadatos,
  • un hash de reversión,
  • una versión del esquema.

Comprobación de cambios

Antes de aplicar la reversión, compare las filas en vivo actuales con las filas posteriores esperadas del plan. Si alguna fila cambió desde la promoción, aborte de forma predeterminada.

PHP
use Merql\Rollback\RollbackDrift;

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

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

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

La comprobación de cambios compara las huellas digitales de las filas, por lo que el orden de las columnas no importa.

Aplicar la reversión

Si no hay cambios inesperados, aplique las operaciones inversas.

PHP
use Merql\Rollback\RollbackPlanApplier;

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

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

La reversión aplica un MergeResult normal creado a partir de operaciones inversas. Sigue la misma ruta transaccional del aplicador que la aplicación normal de combinaciones.

Serialización

Guarde los planes de reversión antes de aplicar la combinación directa. Ese artefacto es la base duradera para una reversión posterior.

PHP
use Merql\Rollback\RollbackPlanSerializer;

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

Las aplicaciones deben almacenar el plan serializado junto con la operación que realizó la escritura en vivo, además de cualquier metadato de auditoría específico del host.