hanya ide yang bagus jika Anda bersikeras mengunci baris tertentu, yang tidak Apa yang kau butuhkan. Anda hanya ingin apa saja baris kualifikasi, tersedia (tidak terkunci). Perbedaan pentingnya adalah ini (mengutip manual untuk Postgres 9.4):FOR UPDATE NOWAIT
Dengan
NOWAIT
, pernyataan tersebut melaporkan kesalahan, daripada menunggu, jika baris yang dipilih tidak dapat segera dikunci.
Kueri yang identik kemungkinan besar akan mencoba mengunci pilihan arbitrer yang sama. FOR UPDATE NOWAIT
hanya akan menyelamatkan dengan pengecualian (yang akan memutar kembali seluruh transaksi kecuali Anda menjebak kesalahan) dan Anda harus mencoba lagi.
Solusi dalam jawaban referensi saya di dba.SE menggunakan kombinasi FOR UPDATE
biasa dalam kombinasi dengan pg_try_advisory_lock()
:
pg_try_advisory_lock
mirip denganpg_advisory_lock
, kecuali fungsi tidak akan menunggu kunci tersedia. Itu akan mendapatkan kunci dengan segera dan mengembalikan true, atau mengembalikan false jika kunci tidak dapat diperoleh dengan segera.
Jadi pilihan terbaik your Anda adalah ... alternatif ketiga:yang baru FOR UPDATE SKIP LOCKED
di Postgres 9.5, yang mengimplementasikan perilaku yang sama tanpa pemanggilan fungsi tambahan.
Manual untuk Postgres 9.5 membandingkan dua opsi, menjelaskan perbedaannya lagi:
Untuk mencegah operasi menunggu transaksi lain dilakukan, gunakan salah satu
NOWAIT
atauSKIP LOCKED
pilihan. DenganNOWAIT
, pernyataan melaporkan kesalahan, daripada menunggu, jika baris yang dipilih tidak dapat segera dikunci. DenganSKIP LOCKED
, setiap baris terpilih yang tidak dapat langsung dikunci akan dilewati.
Pada Postgres 9.4 atau lebih lama opsi terbaik Anda berikutnya adalah menggunakan pg_try_advisory_xact_lock(id)
dalam kombinasi dengan FOR UPDATE
seperti yang ditunjukkan dalam jawaban yang dirujuk:
- PEMBARUAN Pascagres … BATAS 1
(Juga dengan implementasi dengan FOR UPDATE SKIP LOCKED
.)
Sebenarnya Anda mendapatkan pilihan yang sewenang-wenang, bukan benar-benar acak. Itu bisa menjadi perbedaan penting.
Versi kueri Anda yang telah diaudit ada dalam jawaban saya untuk pertanyaan Anda yang lain.