FOR SHARE VS FOR UPDATE

Dalam PostgreSQL, FOR SHARE dan FOR UPDATE adalah klausa penguncian (locking clauses) yang digunakan dalam pernyataan SELECT untuk mengontrol akses konkuren ke baris data dalam transaksi. Kedua klausa ini memungkinkan penguncian baris untuk mencegah perubahan data oleh transaksi lain, tetapi mereka memiliki perbedaan dalam tingkat penguncian dan tujuannya. Berikut penjelasan lengkap beserta contoh konkrit:


1. FOR SHARE

  • Deskripsi: Klausa FOR SHARE digunakan untuk mengunci baris yang dipilih agar dapat dibaca oleh transaksi lain, tetapi mencegah transaksi lain untuk memodifikasi (UPDATE) atau menghapus (DELETE) baris tersebut hingga transaksi saat ini selesai. Ini adalah kunci bersama (shared lock), yang berarti beberapa transaksi dapat mengunci baris yang sama dengan FOR SHARE secara bersamaan, tetapi tidak ada yang bisa memodifikasi baris tersebut.

  • Tujuan: Digunakan ketika Anda ingin memastikan data yang dibaca tidak diubah oleh transaksi lain, tetapi Anda tidak berencana untuk mengubah data tersebut dalam transaksi saat ini.

  • Efek:

    • Baris yang dikunci dengan FOR SHARE tidak dapat diubah atau dihapus oleh transaksi lain.

    • Transaksi lain masih bisa membaca baris tersebut atau mengunci dengan FOR SHARE.

    • Tidak mencegah transaksi lain untuk mengunci baris dengan FOR SHARE juga.

  • Kapan Digunakan: Biasanya digunakan untuk memastikan konsistensi data saat membaca, misalnya saat menghitung total atau membuat laporan berdasarkan data yang tidak boleh berubah selama transaksi.

Contoh Konkrit FOR SHARE

Misalkan ada tabel orders dengan kolom order_id, customer_id, dan amount. Anda ingin membaca data pesanan untuk menghitung total tanpa khawatir data diubah oleh transaksi lain.

BEGIN;

SELECT order_id, amount
FROM orders
WHERE customer_id = 1
FOR SHARE;

-- Lakukan perhitungan atau operasi lain berdasarkan data ini
-- Misalnya, menghitung total amount

COMMIT;

Penjelasan:

  • Transaksi ini mengunci baris di tabel orders untuk customer_id = 1 dengan FOR SHARE.

  • Transaksi lain bisa membaca baris yang sama, tetapi tidak bisa mengubah atau menghapus baris tersebut sampai transaksi ini selesai (COMMIT atau ROLLBACK).

  • Misalnya, jika transaksi lain mencoba menjalankan UPDATE orders SET amount = 100 WHERE order_id = 1, itu akan tertunda hingga transaksi ini selesai.


2. FOR UPDATE

  • Deskripsi: Klausa FOR UPDATE digunakan untuk mengunci baris yang dipilih secara eksklusif, sehingga mencegah transaksi lain untuk membaca baris tersebut dengan FOR SHARE atau FOR UPDATE, serta mencegah modifikasi atau penghapusan baris tersebut. Ini adalah kunci eksklusif (exclusive lock).

  • Tujuan: Digunakan ketika Anda berencana untuk memodifikasi baris yang dipilih dalam transaksi yang sama, sehingga memastikan tidak ada transaksi lain yang dapat mengganggu.

  • Efek:

    • Baris yang dikunci dengan FOR UPDATE tidak dapat dibaca dengan FOR SHARE atau FOR UPDATE oleh transaksi lain, juga tidak dapat diubah atau dihapus.

    • Transaksi lain yang mencoba mengakses baris yang sama akan tertunda hingga transaksi ini selesai.

  • Kapan Digunakan: Biasanya digunakan dalam operasi yang melibatkan pembacaan dan pembaruan data, seperti mengubah status pesanan atau memperbarui saldo akun.

Contoh Konkrit FOR UPDATE

Misalkan Anda ingin mengubah jumlah pesanan (amount) di tabel orders, tetapi ingin memastikan data tidak diubah oleh transaksi lain selama proses.

BEGIN;

SELECT order_id, amount
FROM orders
WHERE order_id = 1
FOR UPDATE;

-- Perbarui data berdasarkan logika
UPDATE orders
SET amount = amount + 50
WHERE order_id = 1;

COMMIT;

Penjelasan:

  • Baris dengan order_id = 1 dikunci secara eksklusif dengan FOR UPDATE.

  • Transaksi lain tidak dapat membaca baris tersebut dengan FOR SHARE atau FOR UPDATE, juga tidak dapat mengubah atau menghapusnya hingga transaksi ini selesai.

  • Ini memastikan bahwa pembaruan (UPDATE) dilakukan tanpa konflik dari transaksi lain.


Perbedaan Utama

Aspek

FOR SHARE

FOR UPDATE

Jenis Kunci

Shared Lock (kunci bersama)

Exclusive Lock (kunci eksklusif)

Akses Membaca

Transaksi lain bisa membaca (SELECT)

Transaksi lain tidak bisa membaca dengan FOR SHARE atau FOR UPDATE

Modifikasi Data

Mencegah UPDATE/DELETE

Mencegah UPDATE/DELETE dan akses FOR SHARE/FOR UPDATE

Tujuan Utama

Melindungi data saat dibaca tanpa modifikasi

Melindungi data saat akan dimodifikasi

Konkurensi

Memungkinkan beberapa transaksi FOR SHARE

Hanya satu transaksi yang bisa mengunci

Kinerja

Lebih ringan, konkurensi lebih tinggi

Lebih ketat, konkurensi lebih rendah


Contoh Kombinasi dalam Skenario Nyata

Bayangkan aplikasi e-commerce dengan tabel inventory yang mencatat stok barang:

CREATE TABLE inventory (
    product_id SERIAL PRIMARY KEY,
    product_name VARCHAR(100),
    stock INT
);

Skenario 1: Menggunakan FOR SHARE

Seorang pengguna ingin melihat stok barang untuk laporan tanpa khawatir stok diubah selama proses:

BEGIN;

SELECT product_name, stock
FROM inventory
WHERE product_id = 1
FOR SHARE;

-- Proses laporan, misalnya menampilkan stok ke pengguna

COMMIT;
  • Baris dengan product_id = 1 terkunci sehingga tidak bisa diubah (misalnya, dikurangi stoknya) oleh transaksi lain selama laporan dibuat.

Skenario 2: Menggunakan FOR UPDATE

Seorang pengguna ingin memesan barang, yang memerlukan pengurangan stok:

BEGIN;

SELECT product_name, stock
FROM inventory
WHERE product_id = 1
FOR UPDATE;

-- Periksa apakah stok cukup
-- Jika cukup, kurangi stok
UPDATE inventory
SET stock = stock - 1
WHERE product_id = 1 AND stock > 0;

COMMIT;
  • Baris dengan product_id = 1 dikunci secara eksklusif, mencegah transaksi lain mengubah stok atau bahkan membaca dengan FOR SHARE hingga pembaruan selesai.


Catatan Tambahan

  • Deadlock: Penggunaan FOR UPDATE dapat menyebabkan deadlock jika dua transaksi mencoba mengunci baris yang sama secara bersamaan. Untuk menghindari ini, pastikan urutan penguncian konsisten di seluruh aplikasi.

  • NOWAIT dan SKIP LOCKED: Kedua klausa ini dapat digunakan dengan FOR SHARE atau FOR UPDATE:

    • NOWAIT: Membuat query gagal segera jika baris sudah terkunci, tanpa menunggu.

    • SKIP LOCKED: Melewati baris yang sudah terkunci dan hanya memproses baris yang tersedia.

    • Contoh: SELECT ... FOR UPDATE NOWAIT atau SELECT ... FOR UPDATE SKIP LOCKED.

  • Performa: FOR SHARE lebih ringan daripada FOR UPDATE karena memungkinkan konkurensi lebih tinggi. Gunakan FOR SHARE jika Anda hanya perlu melindungi data dari perubahan, dan FOR UPDATE jika Anda akan memodifikasi data.


Kesimpulan

  • Gunakan FOR SHARE untuk membaca data dengan aman tanpa rencana modifikasi, misalnya untuk laporan atau validasi.

  • Gunakan FOR UPDATE ketika Anda akan memodifikasi data dan perlu memastikan tidak ada transaksi lain yang mengganggu.

  • Pastikan untuk selalu menggunakan klausa ini di dalam transaksi (BEGIN dan COMMIT/ROLLBACK) agar penguncian berfungsi dengan benar.

perbedaan antara FOR SHARE dan FOR UPDATE di PostgreSQL adalah soal bisa dibaca atau tidak oleh transaksi lain, selain dari tujuan penggunaannya:

  • FOR SHARE: Baris yang dikunci masih bisa dibaca oleh transaksi lain (dengan SELECT biasa atau FOR SHARE), tapi tidak bisa diubah atau dihapus. Ini cocok kalau kamu cuma mau pastiin data stabil saat dibaca, misalnya buat laporan.

  • FOR UPDATE: Baris yang dikunci tidak bisa dibaca dengan FOR SHARE atau FOR UPDATE oleh transaksi lain, apalagi diubah atau dihapus. Ini lebih ketat, digunakan kalau kamu mau modifikasi data dan perlu eksklusivitas penuh.

Jadi, FOR SHARE lebih longgar (izinin baca), sedangkan FOR UPDATE lebih ketat (blokir semua akses kecuali transaksi saat ini).

Last updated