Есть блок «выбрать для обновления» для несуществующих строк

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

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

РЕДАКТИРОВАТЬ:

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

d = queue.fetch();
r = SELECT * FROM table WHERE key = d.key() FOR UPDATE;
if r.empty() then
  r = get_data_from_somewhere_else();

new_r = process_stuff( r );


if Data was present then
   update row to new_r
else
   insert new_r

Этот код выполняется в нескольких потоках, и данные, полученные из очереди, могут относиться к одной и той же строке в базе данных (отсюда и блокировка). Однако, если несколько потоков используют данные, которым нужна одна и та же строка, эти потоки необходимо упорядочить (порядок не имеет значения). Однако эта последовательность не выполняется, если строка отсутствует, потому что мы не получаем блокировку.

РЕДАКТИРОВАТЬ:

На данный момент у меня есть следующее решение, которое мне кажется уродливым.

select the data for update
if zero rows match then
  insert some dummy data   // this will block if multiple transactions try to insert
  if insertion failed then
    // somebody beat us at the race
    select the data for update

do processing

if data was changed then
   update the old or dummy data
else
   rollback the whole transaction

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

18
задан LiKao 8 August 2011 в 11:03
поделиться