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

PEMBARUAN Atom .. PILIH di Postgres

Sementara saran Erwin mungkin yang paling sederhana cara untuk mendapatkan perilaku yang benar (selama Anda mencoba lagi transaksi Anda jika Anda mendapatkan pengecualian dengan SQLSTATE dari 40001), aplikasi yang mengantre berdasarkan sifatnya cenderung bekerja lebih baik dengan permintaan yang memblokir kesempatan untuk mengambil giliran di antrian dibandingkan dengan implementasi PostgreSQL dari SERIALIZABLE transaksi, yang memungkinkan konkurensi lebih tinggi dan agak lebih "optimis" tentang kemungkinan tabrakan.

Contoh kueri dalam pertanyaan, sebagaimana adanya, dalam default READ COMMITTED tingkat isolasi transaksi akan memungkinkan dua (atau lebih) koneksi bersamaan ke keduanya "mengklaim" baris yang sama dari antrian. Apa yang akan terjadi adalah ini:

  • T1 dimulai dan sampai sejauh mengunci baris di UPDATE fase.
  • T2 tumpang tindih dengan T1 dalam waktu eksekusi dan mencoba memperbarui baris itu. Ini memblokir menunggu COMMIT atau ROLLBACK dari T1.
  • T1 melakukan, setelah berhasil "mengklaim" baris.
  • T2 mencoba memperbarui baris, menemukan bahwa T1 sudah memilikinya, mencari versi baru dari baris tersebut, menemukan bahwa baris tersebut masih memenuhi kriteria pemilihan (yang hanya id cocok), dan juga "mengklaim" baris.

Itu dapat dimodifikasi agar berfungsi dengan benar (jika Anda menggunakan versi PostgreSQL yang memungkinkan FOR UPDATE klausa dalam subquery). Cukup tambahkan FOR UPDATE ke akhir subquery yang memilih id, dan ini akan terjadi:

  • T1 dimulai dan sekarang mengunci baris sebelum memilih id.
  • T2 tumpang tindih dengan T1 dalam waktu eksekusi dan memblokir saat mencoba memilih id, menunggu COMMIT atau ROLLBACK dari T1.
  • T1 melakukan, setelah berhasil "mengklaim" baris.
  • Pada saat T2 dapat membaca baris untuk melihat id, ia melihat bahwa ia telah diklaim, sehingga ia menemukan id berikutnya yang tersedia.

Pada bagian REPEATABLE READ atau SERIALIZABLE tingkat isolasi transaksi, konflik penulisan akan menimbulkan kesalahan, yang dapat Anda tangkap dan tentukan sebagai kegagalan serialisasi berdasarkan SQLSTATE, dan coba lagi.

Jika Anda umumnya menginginkan transaksi SERIALIZABLE tetapi Anda ingin menghindari percobaan ulang di area antrian, Anda mungkin dapat melakukannya dengan menggunakan kunci penasehat.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Java Enums, JPA dan Postgres enums - Bagaimana cara membuatnya bekerja bersama?

  2. Postgres:INSERT jika belum ada

  3. Pembandingan Postgres-XL

  4. Deteksi jika baris telah diperbarui atau dimasukkan

  5. Cara Menemukan Nama Batasan di PostgreSQL