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