Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Was genau wird gesperrt, wenn Sie die FOR UPDATE-Sperre von MySQL verwenden?

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.