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

Bagaimana tabel innodb dikunci saat pemicu ON INSERT diproses?

Tentang masalah konkurensi, Anda memiliki 'mudah' cara untuk mencegah masalah konkurensi pada metode ke-2, di dalam transaksi Anda lakukan pemilihan pada baris artikel (For update sekarang implisit). Setiap penyisipan bersamaan pada artikel yang sama tidak akan dapat memperoleh kunci yang sama ini dan akan menunggu Anda.

Dengan tingkat isolasi default yang baru, bahkan tanpa menggunakan tingkat serialisasi dalam transaksi, Anda tidak akan melihat penyisipan secara bersamaan di tabel pemungutan suara hingga akhir transaksi Anda. Jadi SUM Anda harus tetap koheren atau terlihat koheren . Tetapi jika transaksi bersamaan memasukkan suara pada artikel yang sama dan melakukan sebelum Anda (dan yang ke-2 ini tidak melihat sisipan Anda), transaksi terakhir yang dilakukan akan menimpa penghitung dan Anda akan kehilangan 1 suara. Jadi lakukan penguncian baris pada artikel dengan menggunakan pilih sebelumnya (dan lakukan pekerjaan Anda dalam sebuah transaksi, tentu saja). Sangat mudah untuk menguji, buka 2 sesi interaktif di MySQL dan mulai transaksi dengan BEGIN.

Jika Anda menggunakan pemicu, Anda berada dalam transaksi secara default. Tapi saya pikir Anda juga harus melakukan pemilihan pada tabel artikel untuk membuat kunci baris implisit untuk pemicu bersamaan yang berjalan (lebih sulit untuk diuji).

  • Jangan lupa hapus pemicu.
  • Jangan lupa pemicu pembaruan.
  • Jika tidak menggunakan trigger dan tinggal di code, hati-hati setiap insert/delete/update query pada vote harus melakukan kunci baris pada artikel yang bersangkutan sebelum bertransaksi. Tidak sulit untuk melupakannya.

Poin terakhir:buat transaksi lebih sulit, sebelum memulai transaksi gunakan:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

Dengan cara ini Anda tidak memerlukan kunci baris pada artikel, MySQL akan mendeteksi bahwa potensi menulis pada baris yang sama terjadi dan akan memblokir transaksi lain sampai Anda selesai. Tapi jangan gunakan sesuatu yang telah Anda hitung dari permintaan sebelumnya . Kueri pembaruan akan menunggu pelepasan kunci pada artikel, ketika kunci dilepaskan oleh transaksi pertama COMMIT komputasi SUM harus dilakukan lagi untuk menghitung. Jadi kueri pembaruan harus berisi SUM atau buat tambahan.

update articles set nb_votes=(SELECT count(*) from vote) where id=2; 

Dan di sini Anda akan melihat bahwa MySQL cerdas, kebuntuan terdeteksi jika 2 transaksi mencoba melakukan ini sementara penyisipan telah dilakukan dalam waktu bersamaan. Di level serialisasi saya belum menemukan cara untuk mendapatkan nilai yang salah dengan :

   SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
   BEGIN;
       insert into vote (...
       update articles set nb_votes=(
         SELECT count(*) from vote where article_id=xx
       ) where id=XX;
    COMMIT;

Namun bersiaplah untuk menangani transaksi yang melanggar yang harus Anda ulangi.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cronjob atau acara MySQL?

  2. Cara Membuat Tabel Pivot di MySQL

  3. Aktifkan koneksi MySQL jarak jauh:ERROR 1045 (28000):Akses ditolak untuk pengguna

  4. Cara terbaik untuk kesalahan menangkap LOAD DATA LOCAL INFILE?

  5. Memasukkan entri ke kolom JSON di postgres