Поведение заблокированных записей SHARE, почему функции агрегации невозможны? - PullRequest
1 голос
/ 24 октября 2019

На предыдущий вопрос я спросил о том, как можно исключить записи из SELECT, заблокированные с помощью блокировки UPDATE.

Для меня не так очевидно, что на записях, заблокированных с помощью SHARE LOCK, невозможно выполнять функции агрегации.

Почему, и как я могу обойти эту проблему?


Процесс, который я делаю:

  1. Блокировка записей, которые находятся вочередь для удаления с помощью UPDATE lock
  2. Чтобы исключить эти записи для пользователя, на SELECT set SHARE lock, который будет конфликтовать с execute UPDATE lock, и отфильтровать записи
  3. Разбить страницы на выбранные записи(COUNT() используется)

Мой единственный вариант установить флаг в дБ / Redis для фильтрации этих записей?


Ошибка Iполучаю:

PG::FeatureNotSupported: ERROR:  FOR SHARE is not allowed with aggregate functions
: SELECT COUNT(*) FROM "groups" WHERE (groups.deleted_at IS NULL) FOR SHARE OF groups SKIP LOCKED

1 Ответ

1 голос
/ 24 октября 2019

Подвыбор может помочь вам:

SELECT COUNT(*)
FROM (SELECT 1
      FROM groups
      WHERE groups.deleted_at IS NULL
      FOR SHARE SKIP LOCKED) AS q;

Причина этого заключается в том, что запрос, который блокирует строки, должен иметь возможность идентифицировать строку, которая должна быть заблокирована из результата.

src/backend/optimizer/plan/planner.c имеет такой код комментария:

/*
 * We've got trouble if FOR [KEY] UPDATE/SHARE appears inside
 * grouping, since grouping renders a reference to individual tuple
 * CTIDs invalid.  This is also checked at parse time, but that's
 * insufficient because of rule substitution, query pullup, etc.
 */

Таким образом, можно сказать, что этого требует способ его реализации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...