Як ви протестуєте умови гонок у базі даних?


30

Я намагаюся написати код бази даних, щоб переконатися, що він не підпадає під умови перегонів, щоб переконатися, що я заблокував правильні рядки або таблиці. Але я часто задаюся питанням: чи правильний мій код? Чи можна змусити проявити будь-які існуючі умови перегонів? Я хочу бути впевненим, що якщо вони трапляться у виробничому середовищі, моя заявка зробить правильно.

Я, як правило, точно знаю, який паралельний запит, можливо, спричинить проблему, але я не знаю, як змусити їх одночасно запускатись, щоб побачити, чи трапиться правильна поведінка (наприклад, я використав правильний тип блокування), що правильні помилки кинутий тощо.

Примітка: я використовую PostgreSQL та Perl, тому якщо на це не можна відповісти загально, то, ймовірно, слід переназначити як таке.

Оновлення: я вважаю за краще, якщо рішення було б програмним. Таким чином я можу писати автоматизовані тести, щоб переконатися, що немає регресій.


Під "умовою перегону" ви маєте на увазі "тупик"?
Гай

2
@Gaius ... ні, хоча я вірю, що це один можливий результат деяких перегонових умов
ксенотеррацид

Умови перегонів @Gaius в базі даних будуть робити такі дії, як випадання таблиці перед її створенням або оновлення рядка до його вставки. Взагалі я б міг уявити, що вона керується логікою програми поза межами самої бази даних.
Марк D

оновлення рядка до його вставки? це не спричинило б проблеми з db. жодна умова перегонів не буде, як отримання рядка та оновлення, але інший користувач оновить його після отримання рядка, але до того, як ваше оновлення буде оброблене.
ксенотерацид

1
@MarkD - Ні. Існує багато типів перегонових умов, які виникають внаслідок неправильної інкапсуляції атомної одиниці роботи у вашій базі даних. Ось приклад. Пам'ятайте, що "стан перегонів або небезпека гонки - це недолік в електронній системі або процесі, завдяки якому вихід або результат процесу несподівано і критично залежать від послідовності або часу інших подій ". ( джерело )
Нік Чаммас

Відповіді:


11

Я роблю це постійно разом зі своїми модулями T-SQL.

По суті, все, що вам потрібно зробити, це запустити свої модулі з двох або більше з'єднань в циклі протягом декількох хвилин . Зазвичай усі потенційні проблеми виявляються за кілька хвилин, якщо у вас є вікно SQL Server з гідними процесорами.

Я написав кілька прикладів тут і тут .


4

Зазвичай я працюю з інструментом командного рядка RDBMS, просто маючи 2 (або більше) екземплярів CLI. Потім ви можете повторно відтворювати по черзі і, як перегони (це буде виглядати як RPG-дія), SQL заяви, які надсилає ваш додаток. Ви повинні експериментувати / відчувати, що блокуючі системи діють, оскільки ваш CLI трохи "зависне", чекаючи, коли замки будуть звільнені від інших CLI.

Якщо це звучить чітко, як грязь, не соромтесь сказати це ;-)


ви могли б навести крок за кроком прикладу? і чи можуть бути написані програмні тести, щоб зробити те саме?
ксенотеррацид

1

Умови гонки вимагають декількох потоків виконання, тому для тестування цього блоку вам знадобиться запустити один або кілька потоків. В Oracle я використовував DBMS_Scheduler для запуску процесу для імітації другого користувача. Якщо у PostgreSQL / Perl є спосіб ініціювати другий процес програмно, то вам слід зробити щось подібне:

Процес 1 Процес 2

Запуск процесу 2. >>                            
Затримка, щоб дозволити 2 зробити це спрацьовує. 
. Блокування рядків або зміна даних.
. Затримка, щоб дозволити 1 зробити це роботою.
Спроба заблокувати рядки або змінити дані. .
Перевірте, чи правильно виконано поводження. .
Закінчується. .
                                                Закінчується.

Добре бачити, як думати, як поводитися з умовами перегонів і ще важливіше, як їх перевірити.


Я б не описував такі тести як одиничні тести, тому що одиничні тести повинні виконуватись точно так само, як і кожен раз. Умови перегонів не вдається брати участь в процесах з перервами, не абсолютно однаково кожен раз.
АК

@AlexKuznetsov Ви вірні, що несподівані умови перегонів можуть показувати їх переривчасто, однак ОП посилається на очікувані умови, він вважає, що код використовує. Ці конкретні умови можуть бути відтворені точно, а поводження перевірено одиничним тестом.
Лі Риффель

-2

Поки ви не фіксуєте ряди, ви не повинні отримувати перегони, оскільки це, як правило, викликано, коли блокування не встановлено.

Але ви можете зайти в глухий кут, якщо одне питання занадто довго блокує ваше запитання.

Це важко перевірити, оскільки час запитів може змінюватися, коли база даних зростає.

Запити, які добре працюють із 100 000 рядками тестових даних, виходять із діаграми з 10 000 000 рядків.

Цей тип проблеми може бути дуже складно знайти заздалегідь, але багато БД мають певний метод ідентифікації повільних запитів.

Використовуючи цей регулярний режим, ви зможете вловити будь-які запити, що виникають у проблемі, з достатньою попередженням.

Якщо ви робите блокування самостійно, це вже інша історія, але там я не можу допомогти.


@darioo lol Я думав, може бути, WN є абревіатурою чогось ... idk, що він буде означати під "робити блокування самостійно". Якщо він мається на увазі не з ORM, я перевірив код, який видає ORM, він, звичайно, не робить замикаючи право. Це одна з причин, які я хотів би мати можливість перевірити потенційний сценарій стану гонки.
ксенотеррацид

Так, я мав на увазі власну, і зазвичай драйвер бази даних обробляє блокування, рядок, таблицю чи можливо поле, але я просто відкриваюсь для можливості використання деякої БД, яка не обробляє блокування;)

.. Я майже впевнений, якщо у мене є транзакція з декількома операторами, що мій БД не буде знати, які рядки автоматично блокувати ... такі речі, як select for updateби, не існувало, якби вони були ...
xenoterracide
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.