Lewati ke konten

Rollback

Rencana rollback menjelaskan cara membatalkan operasi penggabungan yang dipilih setelah diterapkan. Rencana ini dibuat sebelum penerapan, menggunakan baris aktif yang persis ada tepat sebelum penulisan.

Jangan membuat rollback hanya dari snapshot base. Base adalah leluhur bersama, bukan selalu keadaan aktif yang akan ditimpa.

Membuat Rencana Rollback

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

Rencana menyimpan:

  • ID rencana penggabungan,
  • ID operasi yang dipilih,
  • tabel yang disentuh,
  • operasi kebalikan,
  • baris sebelum perubahan,
  • baris setelah perubahan yang diharapkan,
  • metadata,
  • hash rollback,
  • versi skema.

Pemeriksaan Perubahan

Sebelum menerapkan rollback, bandingkan baris aktif saat ini dengan baris setelah perubahan yang diharapkan dalam rencana rollback. Jika ada baris yang berubah sejak promosi, batalkan secara default.

PHP
use Merql\Rollback\RollbackDrift;

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

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

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

Pemeriksaan perubahan membandingkan sidik jari baris, jadi urutan kolom tidak berpengaruh.

Menerapkan Rollback

Jika tidak ada perubahan, terapkan operasi kebalikannya.

PHP
use Merql\Rollback\RollbackPlanApplier;

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

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

Rollback menerapkan MergeResult biasa yang dibuat dari operasi kebalikan. Proses ini menggunakan jalur penerapan transaksional yang sama dengan penerapan penggabungan biasa.

Serialisasi

Simpan rencana rollback sebelum menerapkan penggabungan ke depan. Artefak tersebut menjadi dasar permanen untuk rollback di kemudian hari.

PHP
use Merql\Rollback\RollbackPlanSerializer;

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

Aplikasi sebaiknya menyimpan rencana yang diserialisasi bersama operasi yang melakukan penulisan aktif, beserta metadata audit khusus host.