Isolation level

Memilih tingkat isolasi mulai dari read committed hingga serializable.

Daftar isi

Topik ini membahas isolation level, yaitu derajat ketat pembacaan transaksi terhadap perubahan yang terjadi bersamaan. PostgreSQL membuka setiap transaksi pada read committed, dan dua tingkat yang lebih ketat, yaitu repeatable read serta serializable, dipilih ketika pola pembacaannya menuntut potret yang stabil atau kebenaran yang terserialisasi.

Blok penyiapan dataset#

bash
# siapkan ulang tabel dan data contoh untuk topik ini
PGOPTIONS='-c client_min_messages=warning' psql -q -U postgres -d perpustakaan <<'SQL'
DROP TABLE IF EXISTS peminjaman, buku, anggota, kategori CASCADE;
CREATE TABLE kategori (id SERIAL PRIMARY KEY, nama TEXT NOT NULL UNIQUE);
CREATE TABLE anggota (id SERIAL PRIMARY KEY, nama TEXT NOT NULL, email TEXT UNIQUE, bergabung DATE NOT NULL, aktif BOOLEAN NOT NULL DEFAULT TRUE);
CREATE TABLE buku (id SERIAL PRIMARY KEY, judul TEXT NOT NULL, penulis TEXT NOT NULL, tahun INTEGER NOT NULL, kategori_id INTEGER REFERENCES kategori(id));
CREATE TABLE peminjaman (id SERIAL PRIMARY KEY, anggota_id INTEGER NOT NULL REFERENCES anggota(id), buku_id INTEGER NOT NULL REFERENCES buku(id), tanggal_pinjam DATE NOT NULL, tanggal_kembali DATE);
INSERT INTO kategori (nama) VALUES ('Pemrograman'), ('Sains'), ('Sejarah'), ('Fiksi'), ('Statistika');
INSERT INTO anggota (nama, email, bergabung, aktif) VALUES ('Ali Rahman', '[email protected]', '2024-01-15', TRUE), ('Budi Santoso', '[email protected]', '2024-03-02', TRUE), ('Citra Kirana', '[email protected]', '2024-05-20', FALSE), ('Dewi Lestari', '[email protected]', '2024-08-11', TRUE), ('Eka Pratama', NULL, '2025-01-30', TRUE);
INSERT INTO buku (judul, penulis, tahun, kategori_id) VALUES ('Dasar Basis Data', 'Sari Wulandari', 2021, 1), ('Jaringan Komputer', 'Ahmad Fauzi', 2019, 1), ('Fisika untuk Pemula', 'Rina Marlina', 2020, 2), ('Kimia Organik', 'Rina Marlina', 2022, 2), ('Sejarah Nusantara', 'Bambang Wijaya', 2018, 3), ('Cerita Kota Lama', 'Nur Aisyah', 2023, 4), ('Statistika Terapan', 'Sari Wulandari', 2022, 5), ('Algoritma dan Struktur Data', 'Ahmad Fauzi', 2021, 1);
INSERT INTO peminjaman (anggota_id, buku_id, tanggal_pinjam, tanggal_kembali) VALUES (1, 1, '2025-03-01', '2025-03-15'), (1, 7, '2025-03-05', '2025-03-20'), (2, 3, '2025-03-10', NULL), (3, 5, '2025-02-20', '2025-03-01'), (2, 1, '2025-04-02', NULL), (4, 6, '2025-04-07', NULL), (5, 8, '2025-04-09', '2025-04-25'), (4, 2, '2025-05-01', NULL);
SQL

Tingkat yang tersedia dan ancaman yang dilayaninya#

Empat tingkat didefinisikan standar SQL, dan PostgreSQL menyediakan tiga di antaranya. Tabel berikut menyandingkan tingkat dengan keanehan yang masih mungkin terjadi padanya.

Tingkatbaca kotorbaca tak konsistenbaris hantu
read committedtidakmungkinmungkin
repeatable readtidaktidakmungkin menurut standar, tidak pada PostgreSQL
serializabletidaktidaktidak

Baca kotor (dirty read), yaitu pembacaan atas perubahan yang belum di-COMMIT, tidak pernah terjadi pada PostgreSQL di tingkat mana pun. Baca tak konsisten (nonrepeatable read) melihat nilai berbeda untuk pembacaan yang sama dalam satu transaksi dan masih terjadi pada read committed. Baris hantu (phantom), yaitu baris baru yang muncul pada pembacaan ulang, ditutup oleh potret transaksi pada repeatable read.

Membaca dan mengatur tingkat sesi#

Tingkat transaksi terbaca melalui SHOW dan diatur per transaksi atau per sesi, dan blok berikut memperlihatkan tingkat bawaan serta cara membuka transaksi pada tingkat yang lebih ketat.

bash
# tingkat bawaan dan transaksi pada tingkat ketat
psql -U postgres -d perpustakaan <<'SQL'
SHOW transaction_isolation;
BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SHOW transaction_isolation;
COMMIT;
SQL
text Keluaran
 transaction_isolation
-----------------------
 read committed
(1 row)

BEGIN
 transaction_isolation
-----------------------
 repeatable read
(1 row)

COMMIT

Tingkat bawaan read committed tampil pada pembacaan pertama, sedangkan transaksi yang dibuka dengan klausul tingkatnya membawa REPEATABLE READ sampai COMMIT. Penyetelan permanen per basis data atau per role dilakukan dengan ALTER DATABASE dan ALTER ROLE, dan pilihan default read committed tetap menjadi keputusan yang disengaja oleh server.

Potret pada repeatable read#

Repeatable read mengunci potret data pada pernyataan pertama transaksi, sehingga seluruh pembacaan selanjutnya melihat keadaan yang sama meskipun transaksi lain melakukan COMMIT di tengah jalan. Kelebihan ini dibayar dengan risiko kegagalan, karena pembaruan atas baris yang berubah oleh transaksi lain menolak transaksi pembacanya dengan error kegagalan serialisasi yang harus diulang dari awal.

Pola aplikasinya adalah mengulang seluruh transaksi bila menerima error tersebut, dan pola ini berlaku juga pada serializable. Transaksi yang pendek serta fokus pada satu tujuan membuat pengulangan menjadi murah, sedangkan transaksi panjang yang menyentuh banyak baris meningkatkan peluang kegagalannya.

Serializable dan pemantauan bahaya#

Serializable menjanjikan hasil yang setara dengan menjalankan transaksi satu per satu, dan PostgreSQL mewujudkannya dengan serializable snapshot isolation yang memantau pola baca-tulis berbahaya antar transaksi. Apabila dua transaksi membaca data yang saling digunakan lalu menulis, salah satunya dibatalkan dengan error kegagalan serialisasi, dan aplikasi yang serius menyiapkan pengulangannya sejak desain.

Biaya pemantauan ini nyata namun terbatas, dan keputusan menaikkan tingkat dilakukan per transaksi yang benar-benar menuntutnya, misalnya perhitungan saldo yang membaca dan menulis baris yang sama. Sisanya tetap di read committed karena keanehannya dinetralkan oleh pola query yang menulis ulang syarat pada UPDATE dan DELETE.

Kesalahan umum#

Kesalahan pertama adalah mengira read committed tidak pernah menyimpan data yang salah, padahal dua pembacaan dalam satu transaksinya dapat melihat dua keadaan, dan kebutuhan potret stabil dijawab repeatable read. Kesalahan kedua adalah menaikkan tingkat tanpa menyiapkan pengulangan, sehingga error kegagalan serialisasi muncul sebagai kegagalan aplikasi alih-alih diulang.

Kesalahan ketiga adalah transaksi panjang pada serializable, yang peluang pembatalannya tumbuh seiring rentang waktunya, dan pemecahan unit kerja yang lebih kecil menurunkan risikonya. Kesalahan keempat adalah mengira SHOW transaction_isolation menunjukkan tingkat transaksi yang belum dibuka, padahal klausul pada BEGIN-lah yang menetapkannya untuk transaksi berikutnya.

Ringkasan#

  • PostgreSQL menyediakan read committed, repeatable read, dan serializable, dengan read committed sebagai bawaan.
  • Baca kotor tidak pernah terjadi, baca tak konsisten ditutup repeatable read, dan serializable menjanjikan urutan tandingan.
  • Repeatable read mengunci potret di pernyataan pertama, dengan risiko pembatalan atas baris yang berubah bersamaan.
  • Tingkat ketat menuntut pola pengulangan pada aplikasi, dan transaksi yang pendek menurunkan peluang kegagalannya.

Referensi#