Xin lỗi vì câu trả lời dài, nhưng điều này sẽ cần được trả lời trong nhiều phần.
1. Khi khóa bảng InnoDB bằng LOCK TABLES
nói chung
Sử dụng LOCK TABLES
với InnoDB trên thực tế hoạt động và có thể được chứng minh với hai trường hợp của MySQL CLI được kết nối với cùng một máy chủ (ký hiệu là mysql-1
và mysql-2
) trong ví dụ dưới đây. Nói chung, nó nên được tránh trong bất kỳ loại bối cảnh sản xuất nào vì tác động đến khách hàng, nhưng đôi khi nó có thể là lựa chọn duy nhất.
Tạo bảng và điền vào bảng đó với một số dữ liệu:
mysql-1> create table a (id int not null primary key) engine=innodb;
Query OK, 0 rows affected (0.02 sec)
mysql-1> insert into a (id) values (1), (2), (3);
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
Khóa bàn:
mysql-1> lock tables a write;
Query OK, 0 rows affected (0.00 sec)
Cố gắng chèn từ mysql-2
, sẽ treo khi khóa:
mysql-2> insert into a (id) values (4);
Bây giờ, hãy mở khóa bảng từ mysql-1
:
mysql-1> unlock tables;
Query OK, 0 rows affected (0.00 sec)
Và cuối cùng là mysql-2
bỏ chặn và trả về:
Query OK, 1 row affected (6.30 sec)
2. Sử dụng phpMyAdmin để thử nghiệm
Phương pháp thử nghiệm của bạn sử dụng phpMyAdmin không hợp lệ vì phpMyAdmin không duy trì kết nối liên tục đến máy chủ giữa các truy vấn từ giao diện web của nó. Để sử dụng bất kỳ loại khóa LOCK TABLES
nào , START TRANSACTION
, v.v., bạn cần duy trì kết nối trong khi khóa được giữ.
3. Khóa tất cả các bảng cần thiết trong quá trình làm việc
Cách MySQL khóa các bảng khi bạn đã sử dụng LOCK TABLES
để khóa rõ ràng mọi thứ, bạn sẽ không thể truy cập bất kỳ bảng nào khác chưa được khóa rõ ràng trong LOCK
... UNLOCK
phiên họp. Trong ví dụ trên, bạn cần sử dụng:
LOCK TABLES my_table WRITE, new_table WRITE, table2 READ;
(Tôi giả sử table2
được sử dụng trong lựa chọn con không phải là lỗi đánh máy.)
4. Hoán đổi bảng nguyên tử sử dụng RENAME TABLE
Ngoài ra, tôi cần lưu ý rằng việc thay thế bảng hiện có bằng DROP TABLE
theo sau là RENAME TABLE
sẽ gây ra một khoảnh khắc ngắn trong đó bảng không tồn tại và điều này có thể gây nhầm lẫn cho các khách hàng mong đợi nó tồn tại. Nói chung tốt hơn là nên làm:
CREATE TABLE t_new (...);
<Populate t_new using some method>
RENAME TABLE t TO t_old, t_new TO t;
DROP TABLE t_old;
Thao tác này sẽ thực hiện hoán đổi nguyên tử của hai bảng.