Menggunakan SELECT FOR UPDATE dalam isolasi baca yang dapat diulang

Halaman ini menjelaskan cara menggunakan klausa FOR UPDATE dalam isolasi baca yang dapat diulang.

Mekanisme penguncian klausa FOR UPDATE berbeda untuk isolasi yang dapat diserialisasi dan bacaan yang dapat diulang. Tidak seperti pada isolasi serialisabel, klausa FOR UPDATE tidak memperoleh kunci dalam isolasi baca yang dapat diulang. Untuk mengetahui informasi selengkapnya tentang kunci di FOR UPDATE, lihat Menggunakan SELECT FOR UPDATE dalam isolasi yang dapat diserialisasikan.

Untuk mempelajari cara menggunakan klausa FOR UPDATE, lihat panduan referensi GoogleSQL dan PostgreSQL FOR UPDATE.

Alasan menggunakan klausa FOR UPDATE

Saat transaksi berjalan dengan isolasi baca yang dapat diulang, data yang dikueri oleh pernyataan SELECT selalu ditampilkan pada stempel waktu snapshot yang ditetapkan untuk transaksi. Jika transaksi kemudian melakukan update berdasarkan data yang dikueri, mungkin ada masalah kebenaran jika transaksi serentak juga mengupdate data yang dikueri. Untuk mengetahui informasi selengkapnya, lihat Konflik baca-tulis dan kebenaran.

Untuk memastikan bahwa data yang dikueri oleh pernyataan SELECT masih valid saat transaksi dilakukan, Anda dapat menggunakan klausa FOR UPDATE dengan isolasi baca yang dapat diulang. Penggunaan FOR UPDATE menjamin kebenaran transaksi meskipun terjadi konflik baca-tulis saat data mungkin telah diubah oleh transaksi lain antara waktu data dibaca dan diubah.

Sintaksis kueri

Bagian ini memberikan panduan tentang sintaksis kueri saat menggunakan klausa FOR UPDATE.

Penggunaan yang paling umum adalah dalam pernyataan SELECT tingkat teratas. Contoh:

SELECT SingerId, SingerInfo
FROM Singers WHERE SingerID = 5
FOR UPDATE;

Klausul FOR UPDATE memastikan bahwa data yang dikueri oleh pernyataan SELECT dan SingerID = 5 masih valid saat transaksi dilakukan, sehingga mencegah masalah kebenaran yang mungkin muncul jika transaksi serentak memperbarui data yang dikueri.

Penggunaan dalam pernyataan WITH

Klausa FOR UPDATE tidak memverifikasi rentang yang dipindai dalam pernyataan WITH saat Anda menentukan FOR UPDATE dalam kueri tingkat luar dari pernyataan WITH.

Dalam kueri berikut, tidak ada rentang yang dipindai yang divalidasi karena FOR UPDATE tidak diteruskan ke kueri ekspresi tabel umum (CTE).

WITH s AS (SELECT SingerId, SingerInfo FROM Singers WHERE SingerID > 5)
SELECT * FROM s
FOR UPDATE;

Jika klausa FOR UPDATE ditentukan dalam kueri CTE, maka rentang yang dipindai dari kueri CTE akan divalidasi.

Dalam contoh berikut, sel SingerId dan SingerInfo untuk baris tempat SingerId > 5 divalidasi.

WITH s AS
  (SELECT SingerId, SingerInfo FROM Singers WHERE SingerId > 5 FOR UPDATE)
SELECT * FROM s;

Penggunaan dalam subkueri

Anda dapat menggunakan klausa FOR UPDATE dalam kueri tingkat luar yang memiliki satu atau beberapa subkueri. Rentang yang dipindai oleh kueri tingkat teratas dan dalam subkueri divalidasi, kecuali dalam subkueri ekspresi.

Kueri berikut memvalidasi sel SingerId dan SingerInfo untuk baris dengan SingerId > 5.

(SELECT SingerId, SingerInfo FROM Singers WHERE SingerId > 5) AS t
FOR UPDATE;

Kueri berikut tidak memvalidasi sel apa pun dalam tabel Albums karena berada dalam subkueri ekspresi. Sel SingerId dan SingerInfo untuk baris yang ditampilkan oleh subkueri ekspresi divalidasi.

SELECT SingerId, SingerInfo
FROM Singers
WHERE SingerId = (SELECT SingerId FROM Albums WHERE MarketingBudget > 100000)
FOR UPDATE;

Digunakan untuk membuat kueri tampilan

Anda dapat menggunakan klausa FOR UPDATE untuk membuat kueri tampilan seperti yang ditunjukkan dalam contoh berikut:

CREATE VIEW SingerBio AS SELECT SingerId, FullName, SingerInfo FROM Singers;

SELECT * FROM SingerBio WHERE SingerId = 5 FOR UPDATE;

Anda tidak dapat menggunakan klausa FOR UPDATE saat menentukan tampilan.

Kasus penggunaan yang tidak didukung

Kasus penggunaan FOR UPDATE berikut tidak didukung:

  • Sebagai mekanisme eksklusi timbal balik untuk menjalankan kode di luar Spanner: Jangan gunakan penguncian di Spanner untuk memastikan akses eksklusif ke resource di luar Spanner. Transaksi dapat dibatalkan oleh Spanner, misalnya, jika transaksi dicoba lagi, baik secara eksplisit oleh kode aplikasi atau secara implisit oleh kode klien, seperti driver JDBC Spanner, hanya dijamin bahwa kunci dipegang selama upaya yang dilakukan.
  • Dikombinasikan dengan saran LOCK_SCANNED_RANGES: Anda tidak dapat menggunakan klausa FOR UPDATE dan saran LOCK_SCANNED_RANGES dalam kueri yang sama, atau Spanner akan menampilkan error. Untuk mengetahui informasi selengkapnya, lihat Perbandingan dengan petunjuk LOCK_SCANNED_RANGES.
  • Dalam kueri penelusuran teks lengkap: Anda tidak dapat menggunakan klausa FOR UPDATE dalam kueri yang menggunakan indeks penelusuran teks lengkap.
  • Dalam transaksi hanya baca: Klausa FOR UPDATE hanya valid dalam kueri yang dieksekusi dalam transaksi baca-tulis.
  • Dalam pernyataan DDL: Anda tidak dapat menggunakan klausa FOR UPDATE dalam kueri dalam pernyataan DDL, yang disimpan untuk dieksekusi nanti. Misalnya, Anda tidak dapat menggunakan klausa FOR UPDATE saat menentukan tampilan.

Langkah Berikutnya