Как заблокировать строку для обновления в Ibm Db2 без таймаутов?

Мне нужно обновить одну строку для каждого соединения в ibm db2 на zos без аномалий данных.

Я выбираю FOR UPDATE WITH RS USE AND KEEP, но возникает проблема. Если один клиент удерживает блокировку во время обновления данных и одновременно второй пользователь пытается прочитать ту же строку - второй пользователь будет ждать, пока блокировка не будет снята.

Мне нужно следующее поведение: второй пользователь получает ошибку, если строка находится под блокировкой.

Возможно ли это в DB2 11?

Ваш вопрос относится к платформе Db2-сервера (т.е. мэйнфрейму Db2 для Z / OS). Когда Db2-сервер работает в Linux / Unix / Windows, приложения могут использовать специальную настройку регистра set current lock timeout NOT WAIT, чтобы сообщить Db2 о немедленном возврате ошибки, если Db2 не может немедленно получить блокировку. Эта функция в настоящее время недоступна для Db2 для Z / OS, но существуют другие подходы.

mao 24.10.2018 12:10
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
2
1
2 363
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

То, что вы просите, - это условный SELECT, если вы можете получить блокировку UPDATE, если я правильно читаю ваш запрос. Я не верю, что это можно сделать. Однако в качестве альтернативы вы можете сделать что-то вроде:

SELECT myCount FROM myTable WHERE ID = someValue

Затем вы можете обновить значение и выполнить UPDATE с предложением WHERE, которое ищет идентификатор и исходное значение myCount. Последовательность вроде

SELECT myCount FROM myTable WHERE ID = someValue
origCount = myCount++
UPDATE myTable WHERE ID = someValue AND myCount = origValue

Если ваше ОБНОВЛЕНИЕ показывает, что обновлены нулевые строки, значит, кто-то обновил его, и вы затем повторяете последовательность или переходите к альтернативной логике.

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

Обычно это называется Оптимистичный параллелизм.

Optimistic concurrency control (OCC) is a concurrency control method applied to transactional systems such as relational database management systems and software transactional memory. OCC assumes that multiple transactions can frequently complete without interfering with each other. While running, transactions use data resources without acquiring locks on those resources. Before committing, each transaction verifies that no other transaction has modified the data it has read. If the check reveals conflicting modifications, the committing transaction rolls back and can be restarted.[1] Optimistic concurrency control was first proposed by H.T. Kung and John T. Robinson

Как я понимаю, для этого есть только альтернативные способы. Например, вы не можете надежно запретить другим приложениям читать строку, заблокированную одним приложением. Запросы, выполняемые с уровнем изоляции незафиксированного чтения, смогут получить доступ даже к исключительно заблокированным строкам. Запросы, выполняемые с уровнем изоляции стабильности курсора с использованием текущей принятой семантики, будут обращаться к предыдущей версии исключительно заблокированной строки. Лучше всего использовать специальное значение (например, «обработка») в столбце состояния, чтобы другие сеансы не обрабатывали ту же строку.

Artyom Karnov 24.10.2018 12:05

Вы можете предотвратить их с помощью блокировки, но это похоже на проблему, которую вы пытались избежать. Вот справочник по семантике блокировки Db2. ibm.com/support/knowledgecenter/en/SSEPEK_11.0.0/perf/src/tp‌ c /….

Hogstrom 24.10.2018 12:27

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

Другие вопросы по теме