Наконец-то, я думаю, что получаю то, что вы собираетесь делать.
Это не проблема «транзакции» как таковая (и в зависимости от количества таблиц, с которыми нужно иметь дело, и требуемых заявлений, возможно, вам даже не понадобится), это проблема -приложения. У вас есть два общих способа борьбы с этим; оптимистичная и пессимистическая блокировка.
Пессимистическая блокировка явно принимает и удерживает замок. Это лучше всего использовать, когда вы можете гарантировать, что вы будет изменить строку плюс связанные с ней вещи, а когда ваши транзакции будут short. Вы использовали бы его в ситуациях, таких как обновление «текущего баланса» при добавлении продаж в учетную запись, как только была сделана покупка (произойдет обновление, короткое время транзакции, поскольку в этот момент не будет выбора).Пессимистическая блокировка становится расстраивающей, если пользователь читает строку, а затем идет на обед (или в отпуск ...).
Оптимистичная блокировка считывает ряд (или набор), а не принимает любые блокировки уровня db. Это лучше всего использовать, если вы просто читаете строки, без какого-либо непосредственного плана по обновлению любого из них. Обычно данные в строке будут содержать значение «версия» (сгенерированный счетчик или последняя обновленная временная метка). Если ваше приложение переходит к обновлению строки, оно сравнивает исходное значение (ы) данных, чтобы убедиться, что оно не было изменено чем-то другим в первую очередь, и предупреждает пользователя, если данные были изменены. Большинство приложений, взаимодействующих с пользователями, должны использовать оптимистичную блокировку. Тем не менее, он требует, чтобы пользователи замечали и обращали внимание на обновленные значения.
Обратите внимание, что, поскольку блокировка редко (и на короткий период) выполняется в оптимистичной блокировке, она обычно не конфликтует с отдельным процессом, который принимает пессимистический замок. Пессимистичное приложение блокировки помешает оптимистическому обновлению заблокированных строк, но не будет их читать.
Также обратите внимание, что это правило обычно не применяется к массовым обновлениям, которые практически не будут взаимодействовать с пользователем (если они есть).
Т.Л., др
Не заблокировать строки при чтении. Просто сравните старые значения с тем, что приложение прочитало в последний раз, и отклоните обновление, если они не совпадают (и предупреждают пользователя). Обучите своих пользователей соответствующим образом реагировать.
С одной стороны, вы говорите, что хотите, чтобы данные были недоступны для других во время транзакции. С другой стороны, вам не нравится, что данные 'select for update' блокируют данные для чтения, что кажется мне явно« недоступным для других ». Никакая блокировка не позволит другим клиентам из * try * выполнить инструкцию обновления; некоторые виды заставят их ждать. Чего вы действительно хотите? –
@Mike Sherrill'Cat Recall «Проблема в том, что я не знаю, если пользователь хочет обновить данные в момент вызова * select * statement. Это ясно после любого * обновления *. Но уже слишком поздно. – agad
Вы * не можете * знать, что другие пользователи хотят делать. Читайте об уровнях изоляции транзакций PostgreSQL (http://www.postgresql.org/docs/current/static/transaction-iso.html). –