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 klausaFOR UPDATE
dan saranLOCK_SCANNED_RANGES
dalam kueri yang sama, atau Spanner akan menampilkan error. Untuk mengetahui informasi selengkapnya, lihat Perbandingan dengan petunjukLOCK_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 klausaFOR UPDATE
saat menentukan tampilan.
Langkah Berikutnya
- Pelajari cara menggunakan klausa
FOR UPDATE
di GoogleSQL dan PostgreSQL. - Pelajari cara Menggunakan SELECT FOR UPDATE dalam isolasi yang dapat diserialisasi.
- Pelajari saran
LOCK_SCANNED_RANGES
. - Pelajari Penguncian di Spanner.