Dat is correct. De rijen in de tabel waaruit wordt gelezen, zijn vergrendeld met een gedeelde vergrendeling (de SELECT
is impliciet LOCK IN SHARE MODE
). Er is geen manier om dit te vermijden. Het is een beetje waar je het systeem om vraagt:kopieer alle rijen die aan een voorwaarde voldoen. De enige manier om ervoor te zorgen dat in feite alle rijen zijn die aan de voorwaarde voldoen en dat die lijst niet verandert tijdens of direct na het uitvoeren van dat statement, is door de rijen te vergrendelen.
Ter verduidelijking waarom u niet kunt INSERT
met group_id = 2
:
Dit heeft te maken met het feit dat uw zoekopdracht specifiek WHERE group_id = 3 AND created < '2014-01-04'
op KEY group_id_created (group_id, created)
. Om alle rijen te doorzoeken die overeenkomen met group_id = 3 AND created < '2014-01-04'
de index wordt achteruit doorlopen, te beginnen met de eerste rij die die voorwaarde overschrijdt de bovengrens, dat is (3, '2014-01-14')
en doorgaan tot het vinden van een rij die niet overeenkomt met de voorwaarde, die sinds created
geen ondergrens heeft, is de eerste rij waar group_id < 3
wat natuurlijk group_id = 2
. is .
Dat betekent dat de eerste rij gevonden met group_id = 2
is ook vergrendeld, wat de rij zal zijn met het maximum created
waarde. Dit maakt het onmogelijk om INSERT
in de "gap" tussen (2, MAX(created))
en (3, MIN(created))
(geen echte SQL natuurlijk, alleen pseudo-SQL), hoewel dit niet specifiek een "gap lock" is.