To je správně. Řádky v tabulce, ze které se čte, jsou uzamčeny sdíleným zámkem (SELECT
je implicitně LOCK IN SHARE MODE
). Neexistuje způsob, jak se tomu vyhnout. Je to něco, o co systém žádáte:zkopírujte všechny řádky, které odpovídají podmínce. Jediným způsobem, jak zajistit, že všechny řádky, které splňují podmínku a že se tento seznam nezmění během nebo bezprostředně po provedení daného příkazu, je uzamknout řádky.
Jako vysvětlení ohledně toho, proč nemůžete INSERT
s group_id = 2
:
Souvisí to s tím, že váš dotaz je konkrétně WHERE group_id = 3 AND created < '2014-01-04'
na KEY group_id_created (group_id, created)
. Chcete-li vyhledat všechny řádky, které odpovídají group_id = 3 AND created < '2014-01-04'
index bude procházet pozpátku počínaje prvním řádkem, který přesahuje tuto podmínku, horní mez, což je (3, '2014-01-14')
a pokračujte, dokud nenajdete řádek, který neodpovídá podmínce, která byla od té doby created
nemá dolní hranici bude první řádek, kde group_id < 3
což je samozřejmě group_id = 2
.
To znamená, že na prvním řádku bylo zjištěno group_id = 2
je také locked, což bude řádek s maximálním created
hodnota. To znemožní INSERT
do "mezery" mezi (2, MAX(created))
a (3, MIN(created))
(samozřejmě ne správné SQL, jen pseudo-SQL), i když se nejedná konkrétně o "zámek mezery".