PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Konsistensi dalam postgresql dengan penguncian dan pilih untuk pembaruan

BEGIN; 
LOCK TABLE slots IN ACCESS EXCLUSIVE MODE; 
UPDATE slots SET job_name = '111' WHERE id IN (SELECT id FROM slots WHERE job_name IS NULL LIMIT 1) RETURNING *;
COMMIT;

Ini tampaknya berfungsi di Baca Berkomitmen. Ini hanya sql (sama dengan kode Anda) dan dapat dieksekusi dalam satu panggilan (lebih cepat).

@Seth Robertson:Tidak aman tanpa LOCK TABLE dan tanpa loop while.

Jika ada transaksi A dan transaksi B secara bersamaan:A akan memilih baris pertama dan B akan memilih baris pertama. A akan mengunci dan memperbarui baris, B harus menunggu hingga A melakukan. Kemudian B akan mengecek kembali kondisi job_name IS NULL. Itu salah dan B tidak akan memperbarui - B tidak akan memilih baris berikutnya tetapi hanya akan memeriksa ulang dan mengembalikan hasil yang kosong.

@joegester:SELECT FOR UPDATE tidak masalah karena semua tabel terkunci.

Mungkin ada cara lain untuk melakukan pekerjaan - jika Anda menghapus dan menyisipkan baris (di tabel lain?) Alih-alih mengatur NULL. Tapi saya tidak yakin bagaimana caranya.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cara men-debug:Kesalahan Internal, transaksi saat ini dibatalkan, perintah diabaikan hingga akhir blok transaksi

  2. PostgREST / PostgreSQL Tidak dapat memperbesar pesan buffer string

  3. Jatuhkan semua fungsi dari database Postgres

  4. Apa cara terbersih untuk mendapatkan waktu lokal saat ini di Postgres?

  5. Simpan kueri umum sebagai kolom?