Това е правилното. Редовете в таблицата, от която се чете, са заключени със споделено заключване (SELECT
е имплицитно LOCK IN SHARE MODE
). Няма начин да се избегне това. Това е нещо като това, за което питате системата:копирайте всички редове, които отговарят на условие. Единственият начин да се гарантира, че всъщност всички редове отговарят на условието и че този списък не се променя по време или непосредствено след изпълнението на този израз, е да заключите редовете.
Като пояснение защо не можете да INSERT
с group_id = 2
:
Това е свързано с това, че вашата заявка е конкретно WHERE group_id = 3 AND created < '2014-01-04'
на KEY group_id_created (group_id, created)
. За да търсите всички редове, които съответстват на group_id = 3 AND created < '2014-01-04'
индексът ще бъде обходен назад, като се започне с първия ред, който надвишава горната граница на това условие, която е (3, '2014-01-14')
и продължава до намиране на ред, който не съответства на условието, което след created
няма долна граница, ще бъде първият ред, където group_id < 3
което разбира се е group_id = 2
.
Това означава, че първият ред се среща с group_id = 2
есъщо заключено, което ще бъде редът с максималния created
стойност. Това ще направи невъзможно INSERT
в "пропастта" между (2, MAX(created))
и (3, MIN(created))
(разбира се, не подходящ SQL, а просто псевдо-SQL), въпреки че това не е конкретно „заключване на празнина“.