Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Ao usar o bloqueio FOR UPDATE do MySQL, o que é exatamente bloqueado?


Por que não tentamos?

Configurar o banco de dados
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');

Agora, inicie duas conexões de banco de dados

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

Conexão 2
BEGIN;

Se o MySQL bloquear todas as linhas, a instrução a seguir bloqueará. Se bloquear apenas as linhas que retorna, não deve bloquear.
SELECT * FROM notification WHERE `date` = '2011-05-02' FOR UPDATE;

E de fato bloqueia.

Curiosamente, também não podemos adicionar registros que seriam lidos, ou seja,
INSERT INTO notification(id, `date`, `text`) values (6, '2011-05-06', 'Notification 6');

blocos também!

Eu não posso ter certeza neste ponto se o MySQL apenas vai em frente e bloqueia a tabela inteira quando uma certa porcentagem de linhas está bloqueada, ou onde é realmente muito inteligente garantir que o resultado do SELECT ... FOR UPDATE consulta nunca pode ser alterada por outra transação (com um INSERT , UPDATE , ou DELETE ) enquanto o bloqueio está sendo mantido.