Разработка простой таблицы событий в MySQL, которую могут опрашивать другие процессы.Как обрабатывать транзакции? - PullRequest
0 голосов
/ 26 июня 2019

Я пытаюсь реализовать простую таблицу событий в MySQL, чтобы другие процессы запрашивали новую информацию. Дизайн довольно прост:

  1. У меня есть таблица событие со столбцом идентификатора AUTO_INCREMENT и дополнительными столбцами, описывающими событие
  2. Через триггеры в других таблицах строки вставляются
  3. Другие процессы опрашивают эту таблицу и, используя столбец ID, знают, где они находятся в «потоке событий», и выбирают соответственно для новой информации.

[2] всегда выполняется внутри транзакции.

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

Пример:

Транзакция 1

start transaction;
insert into event (...) values (...);
commit;

Транзакция 2

start transaction;
insert into event (...) values (...);
commit;

Рассмотрим, когда транзакция 1 сначала вставляется в событие , а затем в транзакцию 2. Событию транзакции 1 будет присвоено 1 в качестве значения для ее автоматически увеличивающегося столбца (при условии, что таблица пуста) , сначала пишет), тогда как транзакции 2 будет дано 2 . Если затем транзакция 2 будет зафиксирована первой, то для внешних процессов, опрашивающих эту таблицу, они просто увидят событие с идентификатором 2 , обработают его и ошибочно предполагают, что с этого момента они должны выбирать строки, имеющие id > 2 . Событие из транзакции 1 фактически потеряно.

Есть ли умный способ обойти это? На практике я хотел бы иметь возможность опрашивать зафиксированных строк в порядке возрастания . К сожалению, я не могу ожидать, что идентификаторы в таблице будут непрерывной последовательностью; транзакции могут эффективно откатываться, создавая пробелы в «неиспользованных» идентификаторах.

Я в тупике. Включить отметку времени с каждым событием и вместо этого всегда выбирать для строк, имеющих отметку времени, превышающую ожидаемую для самых длительных транзакций, а затем игнорировать события, которые уже были обработаны?

Редактировать

Я добавляю больше информации, чтобы попытаться объяснить проблему, которую хочу решить. Общее требование заключается в том, что всякий раз, когда таблица X обновляется, мы хотим уведомлять внешние процессы. Тогда простой дизайн будет следующим: добавить триггер в таблицу X, записать строку в таблицу событий, сделать так, чтобы внешний процесс опрашивал эту таблицу и действовал соответствующим образом.

В идеальном мире я бы хотел, чтобы «событие» вместо этого передавалось в тему и вообще не затрагивало базу данных, но поскольку записи в таблицу X выполняются повсеместно, было бы очень подвержено ошибкам право; наличие триггера, который записывает строку, решает эту проблему очень хорошо На самом деле, если опрос таблицы событий был простым, чтобы получить правильные результаты, мы могли бы просто добавить простое мостовое решение, которое опрашивает и подталкивает к теме.

Редактировать 2

Возможное решение, расширяющее возможности предыдущего редактирования, состоит в том, чтобы отдельный процесс опрашивал таблицу событий, выбирая строки в порядке возрастания по идентификатору. Информация о событиях помещается в тему, а затем удаляется из таблицы. Таким образом, мы не зависим от того, что строки получат более строгие идентификаторы при написании.

...