Perilaku yang Anda gambarkan adalah normal dan diharapkan dalam basis data relasional transaksional apa pun.
Jika PostgreSQL menunjukkan nilai edited
untuk SELECT
pertama itu salah untuk melakukannya - itu disebut "bacaan kotor", dan merupakan berita buruk di database.
PostgreSQL akan diizinkan untuk menunggu di SELECT
sampai Anda melakukan atau memutar kembali, tetapi tidak diharuskan oleh standar SQL, Anda belum memberi tahu bahwa Anda ingin menunggu, dan itu tidak harus menunggu karena alasan teknis apa pun, jadi itu mengembalikan data yang Anda minta untuk segera. Lagi pula, sampai di-commit, update
itu hanya jenis yang ada - itu masih mungkin atau mungkin tidak terjadi.
Jika PostgreSQL selalu menunggu di sini, maka Anda akan segera menemukan situasi di mana hanya satu koneksi yang dapat melakukan apa saja dengan database pada satu waktu. Tidak cantik untuk kinerja, dan sama sekali tidak perlu di sebagian besar waktu.
Jika Anda ingin menunggu UPDATE
secara bersamaan (atau DELETE
), Anda akan menggunakan SELECT ... FOR SHARE
. (Tetapi perlu diketahui bahwa ini tidak akan berfungsi untuk INSERT
).
Detail:
SELECT
tanpa FOR UPDATE
atau FOR SHARE
klausa tidak mengambil kunci tingkat baris apa pun. Jadi ia melihat apa pun baris yang dikomit saat ini, dan tidak terpengaruh oleh transaksi dalam penerbangan apa pun yang mungkin mengubah baris itu. Konsep dijelaskan di bagian MVCC pada dokumen
. Ide umumnya adalah bahwa PostgreSQL adalah copy-on-write, dengan versi yang memungkinkan untuk mengembalikan salinan yang benar berdasarkan apa yang transaksi atau pernyataan dapat "lihat" pada saat dimulai - apa yang disebut PostgreSQL sebagai "snapshot".
Secara default READ COMMITTED
snapshot isolasi diambil pada tingkat pernyataan, jadi jika Anda SELECT
berturut-turut, COMMIT
perubahan dari transaksi lain, dan SELECT
sekali lagi Anda akan melihat nilai yang berbeda bahkan dalam satu transaksi. Anda dapat menggunakan SNAPSHOT
isolasi jika Anda tidak ingin melihat perubahan yang dilakukan setelah transaksi dimulai, atau SERIALIZABLE
isolasi untuk menambahkan perlindungan lebih lanjut terhadap jenis interdependensi transaksi tertentu.
Lihat bab isolasi transaksi dalam dokumentasi .
Jika Anda menginginkan SELECT
untuk menunggu transaksi yang sedang berlangsung untuk melakukan atau mengembalikan perubahan ke baris yang dipilih, Anda harus menggunakan SELECT ... FOR SHARE
. Ini akan memblokir kunci yang diambil oleh UPDATE
atau DELETE
sampai transaksi yang mengambil kunci kembali atau komit.
INSERT
berbeda, meskipun - tupel tidak ada untuk transaksi lain sampai komit. Satu-satunya cara untuk menunggu INSERT
secara bersamaan s adalah untuk mengambil EXCLUSIVE
kunci tingkat tabel, jadi Anda tahu tidak ada orang lain yang mengubah tabel saat Anda membacanya. Biasanya kebutuhan untuk melakukan itu berarti Anda memiliki masalah desain dalam aplikasi - aplikasi Anda tidak boleh peduli jika ada insert
yang tidak dikomit masih dalam penerbangan.
Lihat bab penguncian eksplisit dari dokumentasi .