web-dev-qa-db-fra.com

Pourquoi l'insertion est-elle sélectionnée dans un bloc de table non liée lors de la sélection? Mysql 5.6

SIMPLIFIÉS, j'ai une table 'app' avec un champ d'incrémentation automatique principal App_ID et un champ créé_at DateTime pas NULL.

J'ai une autre table, 'app_subset', avec une touche unique 'app_id'.

Si j'exécute une requête comme celle-ci:

SELECT app_id FROM app;

ensuite, alors que cela fonctionne, j'exécute:

INSERT INTO app (created_at) VALUES (NOW());

L'insert s'exécute immédiatement, n'attendant pas que le choix de la sélection.

Si, cependant, je gère une requête comme celle-ci:

INSERT IGNORE INTO app_subset SELECT app_id FROM app;

puis exécutez le même insert dans l'application:

INSERT INTO app (created_at) VALUES (NOW());

maintenant, l'insert dans les blocs de requête d'application, en attente de la fin de l'insertion.

J'essaie de comprendre pourquoi c'est le cas. Je comprends que les résultats de mon sélection seront modifiés par l'insertion dans l'application, mais cela semble être si le choix d'origine ne bloque pas, puis un insert utilisant les résultats de cette sélection ne doit pas bloquer non plus. J'aimerais pouvoir régler les choses de sorte que c'est le cas de la manière de la manière ou du moins bien comprendre pourquoi il se passe pour que je puisse anticiper des problèmes similaires à l'avenir.

de la réponse de Rolando ci-dessous, on dirait que la lecture non engagée devrait fonctionner et, en effet, lorsque j'exécute:

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

L'insert Ignorer .. Sélectionnez PLUS Permet de bloquer mon insert dans l'application.

Je suis curieux s'il y a un moyen de le faire comme une seule ligne (quelque chose comme :)

INSERT IGNORE INTO app_subset SELECT app_id FROM app LOCK IN NONSHARING MODE;
3
Kem Mason

Réellement, INSERT INTO .. SELECT verrouille la table SELECT

J'ai écrit à ce sujet avant

5
RolandoMySQLDBA