Многопоточность - Предотвращение и контакт с мертвыми блокировками базы данных

Можно использовать OrderedDictionary.

Представляет набор пар ключ/значение, которые доступны ключом или индексом.

5
задан DejanLekic 14 October 2013 в 16:11
поделиться

5 ответов

Обычно используемый подход - это некоторая форма экспоненциального отката. Вместо вашего 1000 * попыток + случайный подход, сделайте задержку экспоненциальной функцией количества попыток. Это обеспечивает минимальную задержку в первых одной или двух попытках, когда вы зашли в тупик, возможно, случайно, но дает гораздо большие задержки позже, когда становится ясно, что соединение действительно перегружено.

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

11
ответ дан 18 December 2019 в 14:47
поделиться

Вот как мы это сделали. Повторяйте и повторяйте транзакцию, пока она не завершится.

Мы не связывались со случайными задержками.

Кроме того, мы сделали фиксацию внутри блока try и откат в обработчике исключений.

Когда у вас есть несколько блокируемых ресурсов и несколько одновременных транзакций, взаимоблокировка неизбежна. Это логическое следствие конкуренции за блокировки.

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

При загрузке вставки (особенно в таблице HEAP) могут (часто) выполняться параллельно без многих проблем с конкуренцией. Если вы откладываете создание индексов, то во время вставки других обновлений не происходит.

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

При обновлении или удалении ничего не помогает.

1
ответ дан 18 December 2019 в 14:47
поделиться

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

1
ответ дан 18 December 2019 в 14:47
поделиться

как это?

short attempts = 0;
boolean success = false;
long delayMs = 0;

Random random = new Random();
do {
try {
     synchronized(ClassName.class) {
         //insert loads of records in table 'x'
      }

    success = true;
} catch (ConcurrencyFailureException e) {
    attempts++;
    success = false;
    delayMs = 1000*attempts+random.nextInt(1000*attempts);

    try {
                    Thread.sleep(delayMs);
            } catch (InterruptedException ie) {
    }
  }
} while (!success);
0
ответ дан 18 December 2019 в 14:47
поделиться

С такой базой данных, как Ingres, вы всегда будете сталкиваться с некоторыми взаимоблокировками, поэтому вы должны предположить, что любая вставка, обновление или удаление завершится ошибкой, и иметь стратегию повторных попыток (как в вашем примере). Вы должны спроектировать свою базу данных таким образом, чтобы конкуренция была сведена к минимуму, а взаимоблокировки возникали редко. Если вы постоянно сталкиваетесь с ошибками транзакций даже после нескольких повторных попыток, то это признак того, что вам придется провести серьезную реконструкцию базы данных (или перейти на такую ​​систему, как Oracle, где обычно можно разрабатывать приложения, чтобы избежать взаимоблокировок с помощью подходящего использования. блокировки на уровне строк).

0
ответ дан 18 December 2019 в 14:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: