Peningkatan counter postgreSQL bersamaan

9

Saya perlu mempertahankan tabel statistik untuk proyek, yang disusun oleh daftar item dan penggunaannya (Pikirkan sesuatu seperti situs web tempat Anda ingin menghitung tampilan halaman). Setiap kali item diterbitkan, saya harus meningkatkan penggunaan item tertentu.

Implementasi pertama saya adalah:

statistics(
  id      integer NOT NULL,
  name    character varying(255) NOT NULL,
  usage   integer NOT NULL DEFAULT 0,
);


UPDATE statistics 
  SET usage = usage + 1
WHERE name = '<name>';

Kekhawatiran saya adalah tentang kinerja dan konkurensi. Proses pembaruan akan dipakai oleh beberapa puluhan (mungkin 80-120) perangkat dan dapat terjadi beberapa kali per detik, jadi pertanyaan saya adalah:

1) akankah metode ini mempertahankan konkurensi? (yaitu jika lebih dari satu perangkat meminta pembaruan "pada saat yang sama", apakah setiap permintaan akan dihitung?)

2) dapatkah Anda menyarankan cara terbaik untuk mencapai hasil? Saya berharap untuk memiliki memuat dalam menulis pembaruan, sementara membaca akan saya lebih sering. Apakah ada fungsi khusus untuk meningkatkan nilai? Saya melihat "urutan" tetapi saya tidak yakin apakah itu cara yang benar ...

Terima kasih banyak sebelumnya atas sarannya

eng.student
sumber

Jawaban:

5

Pembaruan kedua akan menunggu pembaruan sebelumnya pada baris yang sama untuk dikomit, tetapi kemudian akan melihat nilai yang dikomit.

Asumsikan dua transaksi bersamaan memperbarui baris yang sama dengan nilai awal 0

Transaksi Waktu 1 nilai T1 Nilai transaksi 2 nilai T2
-------------------------------------------------- ------------
1 pembaruan ... 1 0
2 1 pembaruan .. "tidak terdefinisi"
                                (menunggu) 
3 komit 1 2
4 1 komit 2
5 2 2 

"Nilai T1" dan "Nilai T2" berarti nilai yang dilihat transaksi.

Jika Anda ingin memastikan bahwa Anda menangkap situasi di mana ada perubahan "tidak kompatibel" (mis. Satu transaksi mengatur usagekolom ke nilai tertentu, daripada hanya menambahkannya), Anda dapat menempatkan semua transaksi ke tingkat isolasi "serializable". Tetapi Anda harus bersiap untuk penanganan kesalahan.

Pembaruan untuk nama yang berbeda dapat berjalan secara bersamaan tanpa menunggu (karena baris yang berbeda terpengaruh).

SELECTs tidak akan pernah diblokir tetapi hanya akan melihat nilai yang sudah dikomit.

seekor kuda tanpa nama
sumber