Varför försöker vi inte bara?
Konfigurera databasen
CREATE DATABASE so1;
USE so1;
CREATE TABLE notification (`id` BIGINT(20), `date` DATE, `text` TEXT) ENGINE=InnoDB;
INSERT INTO notification(id, `date`, `text`) values (1, '2011-05-01', 'Notification 1');
INSERT INTO notification(id, `date`, `text`) values (2, '2011-05-02', 'Notification 2');
INSERT INTO notification(id, `date`, `text`) values (3, '2011-05-03', 'Notification 3');
INSERT INTO notification(id, `date`, `text`) values (4, '2011-05-04', 'Notification 4');
INSERT INTO notification(id, `date`, `text`) values (5, '2011-05-05', 'Notification 5');
Starta nu två databasanslutningar
Anslutning 1
BEGIN;
SELECT * FROM notification WHERE `date` >= '2011-05-03' FOR UPDATE;
Anslutning 2
BEGIN;
Om MySQL låser alla rader, blockeras följande uttalande. Om den bara låser raderna som den returnerar, bör den inte blockera.
SELECT * FROM notification WHERE `date` = '2011-05-02' FOR UPDATE;
Och det blockerar verkligen.
Intressant nog kan vi inte heller lägga till poster som skulle läsas, d.v.s.
INSERT INTO notification(id, `date`, `text`) values (6, '2011-05-06', 'Notification 6');
blockerar också!
Jag kan i nuläget inte vara säker på om MySQL bara går vidare och låser hela tabellen när en viss procentandel av raderna är låsta, eller om det faktiskt är riktigt intelligent att se till att resultatet av SELECT ... FOR UPDATE
fråga kan aldrig ändras av en annan transaktion (med en INSERT
, UPDATE
, eller DELETE
) medan låset hålls.