Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

beberapa permintaan ke node express masalah sinkronisasi mysql

Saya tidak tahu knex secara detail dan dari pencarian cepat, knex saat ini tidak mendukung penggunaan "batas" pada pernyataan pembaruan jadi hanya deskripsi pendekatan umum.

Pertama lakukan pembaruan untuk baris yang cocok dengan kriteria, lalu pilih baris yang diperbarui tersebut.

Jadi, pertama-tama lakukan operasi pembaruan yang menetapkan id pengguna saat ini ke baris pertama yang belum diproses yang tidak memiliki pengguna yang ditetapkan atau sudah memiliki pengguna yang sama yang ditetapkan:

update rows 
    set assignedTo = user.id 
    where assignedTo=0 or assignedTo=user.id 
    order by createdAt asc 
    limit 1

Saya pikir ini bisa bekerja seperti ini dengan knex menggunakan kueri mentah tetapi belum mencobanya:

await knex.raw('update rows set assignedTo = :userid where assignedTo=0 or assignedTo= :userid  order by createdAt asc limit 1', {userid: user.id})

Ini akan mencari baris pertama (yang paling awal dibuat) yang belum ditetapkan atau sudah ditetapkan ke pengguna yang sama dan kemudian menetapkan pengguna itu. Ini terjadi sekaligus.

Anda kemudian dapat mencari baris yang ditetapkan untuk pengguna:

const notProcessed = await knex('rows')
    .select('*'')
    .whereRaw(`status='Not-Processed' and assignedTo=${user.id}`)
    .orderByRaw('createdAt asc')
    .first();

Perhatikan bagaimana sekarang kita secara eksplisit hanya mencari baris yang sudah ditetapkan ke pengguna.

Gabungan

await knex.raw('update rows set assignedTo = :userid where assignedTo=0 or assignedTo= :userid  order by createdAt asc limit 1', {userid: user.id})
const notProcessed = await knex('rows')
    .select('*'')
    .whereRaw(`status='Not-Processed' and assignedTo=${user.id}`)
    .orderByRaw('createdAt asc')
    .first();

Jelas Anda tidak perlu memilih jika Anda tidak ingin langsung bekerja dengan baris.

Masalahnya adalah ketika beberapa permintaan ditangani pada saat yang sama, Anda harus membayangkan beberapa contoh kode yang berjalan pada waktu yang sama secara paralel. Jadi, dengan kode asli Anda, dua permintaan dapat melakukan pilihan Anda secara bersamaan sebelum salah satu dari mereka melakukan pembaruan. Jadi, keduanya akan mendapatkan baris yang sama.

Dengan segera memperbarui baris dalam pernyataan, bahkan ketika dua pernyataan dijalankan secara paralel, database akan memastikan bahwa mereka tidak melihat baris yang sama.

Pendekatan alternatif untuk solusi adalah dengan menggunakan mutex (seperti misalnya async-mutex ) di sekitar kode asli Anda untuk memastikan bahwa operasi pemilihan dan pembaruan asli Anda bersifat atomik (terjadi dalam sekali jalan), tetapi ini kemungkinan besar akan meningkatkan waktu respons aplikasi Anda karena dalam beberapa situasi satu operasi penanganan permintaan harus menunggu yang lain satu untuk melanjutkan.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Pencadangan Basis Data Harian menggunakan Cron Job

  2. Pelengkapan otomatis di MySQL di bawah Windows

  3. Cara mengunci baris untuk dipilih di MySQL

  4. Hentikan dan kembalikan jika salah satu dari beberapa pernyataan yang disiapkan gagal

  5. Mengapa menambahkan '*' ke kueri MySQL menyebabkan kesalahan sintaks?