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

Penguncian Tak Terduga untuk Tabel dengan Kunci Utama &Kunci Unik

Masalah yang Anda alami terjadi karena MySQL tidak hanya mengunci baris tabel untuk nilai yang akan Anda masukkan, tetapi juga mengunci semua nilai yang mungkin antara id sebelumnya dan id berikutnya secara berurutan, jadi, gunakan kembali contoh Anda di bawah ini:

DROP TABLE IF EXISTS foo;
CREATE TABLE `foo` (
  `i` INT(11) NOT NULL,
  `j` INT(11) DEFAULT NULL,
  PRIMARY KEY (`i`),
  UNIQUE KEY `jk` (`j`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
INSERT INTO foo VALUES (5,5), (8,8), (11,11);

Misalkan Anda memulai dengan transaksi TX1:

START TRANSACTION;
REPLACE INTO foo VALUES(8,8);

Kemudian jika Anda memulai transaksi TX2 , apapun INSERT atau REPLACE menggunakan id antara 5 dan 11 akan dikunci:

START TRANSACTION;
REPLACE INTO foo VALUES(11,11);

Sepertinya MySQL menggunakan penguncian semacam ini untuk menghindari "masalah hantu" yang dijelaskan di sini:http://dev.mysql.com/doc/refman/5.0/en/innodb-next-key-locking.html , MySQL menggunakan "penguncian tombol berikutnya", yang menggabungkan penguncian baris indeks dengan penguncian celah, ini berarti bagi kami bahwa itu akan mengunci banyak kemungkinan id antara id sebelumnya dan berikutnya, dan akan mengunci id sebelumnya dan berikutnya juga .

Untuk menghindarinya coba buat algoritme server yang menyisipkan record-record Anda agar record-record yang disisipkan pada transaksi yang berbeda tidak tumpang tindih, atau setidaknya jangan mengeksekusi semua transaksi Anda secara bersamaan agar TX tidak harus saling menunggu.



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

  2. PHP Daftar Pengguna dari Database SQL di Tabel

  3. Membuat tabel baru di Laravel berdasarkan input pengguna?

  4. SQL Query untuk menunjukkan tanggal terdekat?

  5. Mengapa masih ada perintah yang tidak sinkron; Anda tidak dapat menjalankan perintah ini sekarang kesalahan