Perintah dan konteks
Pewawancara memberikan Anda dua transaksi konkuren. Keduanya membaca aturan bisnis yang sama tetapi memperbarui baris data yang berbeda. Keduanya melihat kapasitas yang cukup, namun status akhirnya melanggar aturan tersebut. Jelaskan apa yang diizinkan oleh tingkat isolasi yang lebih lemah, bagaimana Serializable mencegah hasil tersebut, dan bagaimana aplikasi menangani kegagalan.
Hal ini menguji batas-batas kontrol konkurensi basis data. Bedakan visibilitas snapshot, lock waiting, deteksi konflik, dan retry pada aplikasi alih-alih sekadar menghafal empat nama tingkat isolasi.
Apa yang sedang diuji oleh pewawancara
Mereka menginginkan interleaving konkret yang menjelaskan anomali tersebut, perbedaan antara "setara dengan suatu urutan serial tertentu" dan "setiap transaksi mengantre", serta penjelasan mengapa membatalkan transaksi (abort) adalah bagian dari perlindungan tersebut. Panduan wawancara produk Amazon meminta kandidat untuk menghubungkan keputusan dengan metrik dan bukti; jawaban teknis juga perlu menyatakan jaminan, biaya/overhead, dan tindakan aplikasi.
Pertanyaan untuk diklarifikasi terlebih dahulu
Tanyakan basis data dan implementasi mana yang digunakan, tingkat isolasi default, pola baca/tulis, apakah invarian dapat dinyatakan sebagai constraint basis data, dan apakah pemanggil dapat mengulang transaksi dengan aman. Repeatable Read pada PostgreSQL menggunakan snapshot transaksi; Serializable menambahkan deteksi kemungkinan anomali serialisasi dan membatalkan salah satu transaksi. Nilai default dan implementasi berbeda di berbagai basis data.
Struktur jawaban 30 detik
Mulailah dengan kesimpulan: Serializable mengharuskan hasil yang di-commit setara dengan suatu eksekusi serial, tetapi ini tidak berarti semua transaksi harus mengantre. Gunakan interleaving write-skew dua transaksi untuk menunjukkan batas Repeatable Read, lalu jelaskan bahwa Serializable mendeteksi dependensi yang berbahaya dan mengembalikan kegagalan serialisasi. Akhiri dengan me-retry seluruh transaksi, membatasi jumlah percobaan, idempotensi, dan pemantauan konflik.
Analisis langkah demi langkah
Langkah 1: Jelaskan anomali dengan sebuah interleaving
Misalkan aturannya adalah "setidaknya satu dokter jaga harus tetap aktif." Transaksi A membaca bahwa dokter B aktif; transaksi B membaca bahwa dokter A aktif. A menandai dirinya tidak bertugas dan B melakukan hal yang sama. Masing-masing transaksi hanya memperbarui barisnya sendiri, sehingga tidak ada konflik write-write langsung, tetapi status akhirnya tidak menyisakan siapa pun yang berjaga. Write skew ini menunjukkan bahwa snapshot yang valid secara individual tidak selalu mempertahankan setiap invarian bisnis gabungan.
Langkah 2: Pisahkan stabilitas snapshot dari kesetaraan serial
Repeatable Read memberikan tampilan yang stabil kepada satu transaksi dan tidak mengekspos commit konkuren yang terjadi kemudian. Tingkat ini tidak menjamin bahwa seluruh rangkaian baca dan tulis dapat disusun menjadi urutan serial yang mempertahankan setiap aturan bisnis. Isolasi snapshot dapat meningkatkan konkurensi, tetapi aplikasi harus mengetahui anomali apa saja yang dicegahnya dan apa saja yang masih mungkin terjadi.
Langkah 3: Nyatakan jaminan Serializable
Serializable bertujuan agar hasil yang di-commit setara dengan eksekusi di mana transaksi dijalankan satu per satu. Suatu implementasi dapat menggunakan lock, deteksi konflik, atau Serializable Snapshot Isolation; ini tidak mengharuskan setiap operasi baca memblokir setiap transaksi lainnya. PostgreSQL memantau dependensi baca-tulis dan menggagalkan transaksi ketika dependensi tersebut dapat membentuk anomali serialisasi.
Langkah 4: Jelaskan mengapa seluruh transaksi harus di-retry
Kegagalan dapat terjadi pada saat commit atau mendekati commit, dan basis data tidak dapat menyimpulkan apakah logika aplikasi aman untuk diulang. Lakukan rollback dan jalankan ulang dari pembacaan pertama, bukan hanya mengirim ulang UPDATE terakhir. Batasi jumlah retry dan gunakan backoff. Pindahkan efek samping eksternal ke setelah commit, atau isolasi dengan kunci idempotensi dan catatan event yang persisten.
Langkah 5: Bandingkan biaya dan tentukan pilihan
Serializable dapat meningkatkan konflik, retry, overhead pengelolaan memori atau lock, serta latensi tergantung pada pola akses. Untuk saldo, inventaris, atau kuota dengan invarian yang kuat, biaya tersebut mungkin sepadan. Laporan read-only yang menoleransi aproksimasi dapat menggunakan tingkat yang lebih lemah. Pilihlah dengan mempertimbangkan invarian, konkurensi, target latensi, dan kemampuan penanganan kegagalan secara bersamaan.
Contoh jawaban berkualitas tinggi
Serializable menjamin bahwa setiap hasil yang di-commit setara dengan suatu urutan serial; ini tidak mengharuskan basis data mengantrekan semua transaksi. Dengan aturan "setidaknya satu dokter sedang bertugas", dua transaksi Repeatable Read masing-masing dapat melihat dokter lain sedang bertugas dan kemudian menandai diri mereka sendiri tidak bertugas. Keduanya tidak memperbarui baris yang sama, namun bersama-sama menciptakan write skew dan melanggar invarian.
Serializable mendeteksi dependensi baca-tulis yang dapat menciptakan anomali ini dan mengakhiri salah satu transaksi dengan kegagalan serialisasi. Aplikasi harus melakukan rollback dan me-retry dari awal, dengan jumlah percobaan terbatas dan backoff. Pengiriman email, penagihan, dan efek eksternal lainnya harus dilakukan setelah commit atau di balik kunci idempotensi. Saya akan menggunakan tingkat yang lebih kuat untuk inventaris, saldo, dan kuota, serta mengevaluasi isolasi yang lebih lemah untuk laporan aproksimasi sambil memantau tingkat anomali dan retry.
Kesalahan umum dan perbaikannya
- Mengatakan Serializable berarti antrean global: katakan "setara dengan suatu urutan serial."
- Hanya menyebutkan lock: sertakan deteksi konflik dan perbedaan implementasi.
- Hanya me-retry pernyataan SQL terakhir: jalankan ulang seluruh transaksi.
- Mengabaikan efek samping: gunakan event pasca-commit, kunci idempotensi, atau catatan deduplikasi.
- Mengatakan Repeatable Read tidak memiliki anomali: akui adanya write skew atau anomali serialisasi.
Pertanyaan lanjutan dan jawabannya
Mengapa transaksi read-only masih bisa gagal pada Serializable?
Pembacaannya dapat terlibat dalam dependensi yang membuat hasil commit transaksi lain menjadi non-serializable. Basis data dapat membatalkan transaksi untuk mempertahankan jaminan global; aplikasi harus memperlakukan error tersebut sebagai error yang dapat di-retry jika operasinya aman untuk diulang.
Haruskah setiap permintaan menggunakan Serializable?
Tidak. Mulailah dari invarian bisnis dan beban kerja. Gunakan tingkat yang lebih kuat jika anomali tidak dapat diterima, dan pilih tingkat yang lebih lemah jika pembacaan perkiraan dapat diterima serta trade-off performanya telah diukur.
Mengapa retry harus mencakup semua pembacaan?
Keputusan terkait konflik bergantung pada kumpulan operasi baca dan tulis yang lengkap. Menjalankan ulang penulisan terakhir saja dapat menggunakan asumsi yang basi dan menciptakan kembali anomali yang sama.
Bagaimana Anda memantau apakah retry berjalan dengan sehat?
Lacak kegagalan serialisasi, tingkat keberhasilan retry, latensi retry, percobaan yang habis, dan error yang terlihat oleh pengguna berdasarkan jenis transaksi. Tingkat retry yang tinggi dapat mengindikasikan invarian yang mengalami persaingan tinggi atau pola akses yang perlu dirancang ulang.