Строка блокировки, которая в настоящее время вставляется, чтобы избежать условий гонки при чтении того же самого - PullRequest
0 голосов
/ 12 мая 2018

У меня есть система, в которой я буду отправлять события как часть транзакций при вставке строк в базу данных.

Это делается для того, чтобы события отправлялись только для успешной вставки, а вставкиОткат отправки события Incase завершился неудачей.

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

Я хочу добиться, чтобы при вставке строки A любые процессы, пытающиесячтение строки A должно ждать, пока транзакция строки A не будет завершена

Это разумный подход и как его лучше всего достичь?

Для двух процессов A и B

Как это работает в настоящее время

  1. A Начать транзакцию
  2. A Попытка вставки
  3. Событие отправки
  4. B Получает событие и пытается прочитать вставленную строку
  5. B Возникло исключение, поскольку запись еще не видна
  6. A совершает транзакцию

Как бы я хотел, чтобы это работало

  1. A Начать транзакцию
  2. A Попытка вставки
  3. Событие отправки
  4. B Получает событие и пытается прочитать вставленную строку
  5. BВ настоящее время транзакция заблокирована транзакцией, поэтому она ждет, пока ее не освободят
  6. Транзакция фиксации A
  7. B Блокировка снята, и вновь вставленная строка возвращается

1 Ответ

0 голосов
/ 16 мая 2018

Исходя из комментариев и комментариев, я думаю, что главная проблема здесь в том, что вы хотите, чтобы «А» отправляла событие на основе содержимого незафиксированной строки, а вы хотите, чтобы «Б»читайте и действуйте в этом незафиксированном ряду.Но в теории отношений и в базах данных SQL вы не знаете, удастся ли выполнить коммит.Фиксация может завершиться неудачей по многим причинам - не только из-за сбоя некоторых ограничений, но и из-за недостатка разрешений или дискового пространства.

Чтобы позаимствовать слова из одного из ваших комментариев, dbms управляет переходом базы данных из одного согласованного состояния в другое.Неизвестные строки, как известно, не являются частью согласованного состояния базы данных.Только успешно зафиксированные строки являются частью согласованного состояния базы данных.

Поэтому я думаю, что в общем случае вам нужно «A» для фиксации, прежде чем «B» попытается прочитать новую строку.И я думаю, что это действительно так, даже если вы переключаетесь на dbms, который поддерживает уровень изоляции транзакции read uncommitted.(PostgreSQL не делает, по крайней мере, не так, как вы думаете.)

Это означает, что «B» будет отвечать за удаление новой строки (или за сообщение «A», чтобы удалить ее), если «отправка»выходит из строя.Ни «A», ни «B» не могут откатить совершенную транзакцию.

Для другого процесса, "C", может иметь смысл наблюдать за действиями "A" и "B".

...