Warum versuchen wir es nicht einfach?
Datenbank einrichten
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');
Starten Sie nun zwei Datenbankverbindungen
Verbindung 1
BEGIN;
SELECT * FROM notification WHERE `date` >= '2011-05-03' FOR UPDATE;
Verbindung 2
BEGIN;
Wenn MySQL alle Zeilen sperrt, würde die folgende Anweisung blockieren. Wenn es nur die Zeilen sperrt, die es zurückgibt, sollte es nicht blockieren.
SELECT * FROM notification WHERE `date` = '2011-05-02' FOR UPDATE;
Und tatsächlich blockiert es.
Interessanterweise können wir auch keine Datensätze hinzufügen, die gelesen würden, also
INSERT INTO notification(id, `date`, `text`) values (6, '2011-05-06', 'Notification 6');
blockiert auch!
Ich kann an dieser Stelle nicht sicher sein, ob MySQL einfach fortfährt und die gesamte Tabelle sperrt, wenn ein bestimmter Prozentsatz von Zeilen gesperrt ist, oder wo es tatsächlich wirklich intelligent ist, sicherzustellen, dass das Ergebnis von SELECT ... FOR UPDATE
Abfrage kann niemals durch eine andere Transaktion geändert werden (mit einem INSERT
, UPDATE
, oder DELETE
), während die Sperre gehalten wird.