Надежно воспроизводит раздоры БД
Мы сталкиваемся с некоторой регулярностью конфликтов в таблице базы данных и хотели бы оценить ряд различных вариантов решения этой проблемы.
для этого мне нужно воспроизвести в тестовом примере конфликт на столе (любой таблице) с повторяемой надежностью.
подход, который я рассматриваю, состоял бы в том, чтобы изменить семантику блокировки (например, java.util.concurrent.locks.ReentrantLock
) и снять блокировку, когда начинается запись в таблицу, позволяя выполнять все чтения в то время, когда начинается запись.
Таким образом, поэтому один поток записи удерживает блокировку до того, как незадолго до выполнения вставки в таблицу, а затем освобождения блокировки, несколько потоков чтения будут пытаться выполнить операторы выбора для одной и той же таблицы.
Интересно, были ли какие-либо мысли о таком подходе или есть более простой подход, который мог бы с 100% -ной достоверностью воспроизвести конфликт на таблице базы данных.
Спасибо
2 ответа
Вы можете использовать CountDownLatch с количеством 1
,
final CountDownLatch barrier = new CountDownLatch(1);
Вы запускаете все читательские потоки, первое действие которых
barrier.await();
тогда автор темы может
barrier.countDown();
в этот момент все читатели весело выстрелят.
От вашей базы данных зависит, насколько легко вызвать в ней конфликт. Например, если вы используете Oracle, выполнение выбора никогда не приведет к конфликту.
Самый простой способ вызвать конфликт в базе данных - сделать выбор для чтения в строке, которую, как вы знаете, нужно обновить.
Изменить: После перечитывания вопроса, я вижу, что вы, кажется, больше заботитесь о конкуренции "читатель" в базе данных, чем конкуренции за обновление. Вышеприведенная идея может быть использована для принудительной конкуренции за обновление, но не от читателя.
В случае, когда вы хотите запустить массовое число читателей, чтобы заполнить базу данных выборками, что не должно вызывать фактического конфликта, только голодание, тогда вы можете использовать CountDownLatch, как упомянуто в другом ответе, или сделать это по старинке. с Object.wait/Object.notifyAll(), если вы вынуждены работать в JVM до 1.5.
Изменить 2: После прочтения комментария, вероятно, самый простой способ эмулировать возникшую конкуренцию - использовать команду таблицы блокировки Sybase. Просто заблокируйте стол, включите выбор и затем разблокируйте стол. Затем все селекты должны срабатывать... это также имеет преимущество в том, что они наиболее точно подражают ситуации, которую вы пытаетесь смоделировать.