Mysql
 sql >> Database >  >> RDS >> Mysql

Quando si utilizza il blocco FOR UPDATE di MySQL, cosa è esattamente bloccato?

Perché non proviamo e basta?

Configura il database

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

Ora avvia due connessioni al database

Connessione 1

BEGIN;
SELECT * FROM notification WHERE `date` >= '2011-05-03' FOR UPDATE;

Connessione 2

BEGIN;

Se MySQL blocca tutte le righe, la seguente istruzione bloccherebbe. Se blocca solo le righe che restituisce, non dovrebbe bloccarsi.

SELECT * FROM notification WHERE `date` = '2011-05-02' FOR UPDATE;

E infatti si blocca.

È interessante notare che non possiamo nemmeno aggiungere record che verrebbero letti, ad es.

INSERT INTO notification(id, `date`, `text`) values (6, '2011-05-06', 'Notification 6');

blocchi pure!

Non posso essere sicuro a questo punto se MySQL va avanti e blocca l'intera tabella quando una certa percentuale di righe è bloccata, o dove sia effettivamente davvero intelligente nell'assicurarsi che il risultato di SELECT ... FOR UPDATE la query non può mai essere modificata da un'altra transazione (con un INSERT , UPDATE o DELETE ) mentre si tiene premuto il lucchetto.