Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Khóa bất ngờ cho bảng với khóa chính &khóa duy nhất

Sự cố bạn đang gặp phải xảy ra vì MySQL không chỉ khóa hàng của bảng cho một giá trị bạn sẽ chèn, nó khóa tất cả các giá trị có thể có giữa id trước đó và id tiếp theo theo thứ tự, vì vậy, hãy sử dụng lại ví dụ dưới đây của bạn:

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);

Giả sử bạn bắt đầu với giao dịch TX1:

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

Sau đó, nếu bạn bắt đầu một giao dịch TX2 , bất cứ điều gì INSERT hoặc REPLACE sử dụng id từ 5 đến 11 sẽ bị khóa:

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

Có vẻ như MySQL sử dụng loại khóa này để tránh "vấn đề ma" được mô tả ở đây: http://dev.mysql.com/doc/refman/5.0/en/innodb-next-key-locking.html , MySQL sử dụng "khóa tiếp theo", kết hợp khóa hàng chỉ mục với khóa khoảng cách, điều này có nghĩa là đối với chúng tôi, nó sẽ khóa rất nhiều id có thể có giữa id trước đó và id tiếp theo, đồng thời cũng sẽ khóa id trước đó và tiếp theo .

Để tránh điều này, hãy thử tạo một thuật toán máy chủ chèn các bản ghi của bạn để các bản ghi được chèn trong các giao dịch khác nhau không trùng lặp hoặc ít nhất là không thực hiện tất cả các giao dịch của bạn cùng một lúc nên TX không phải đợi nhau.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Xếp hạng hàng trong Chế độ xem MySQL

  2. Hibernate Exception trên MySQL Cross Join Query

  3. Sử dụng PHP "chèn nhiều" để chèn tất cả 4 hàng cùng một lúc

  4. Sự cố hàm tổng hợp MySQL

  5. Đồng bộ hóa SQL Server và MySQL