Я думаю, ви намагаєтеся вирішити проблему неправильним способом. Те, що вам потрібно, - це максимальний захист послідовності баз даних. Якщо дві особи одночасно виконують збережену процедуру, послідовність бази даних може бути порушена.
Для захисту від різного роду невідповідностей баз даних стандарт SQL має чотири рівні ізоляції транзакцій:
- ЧИТАЙТЕ НЕЗАПАСНО, коли в основному транзакції втрачають свою цінність, а інші транзакції бачать брудні дані. Не використовуйте це!
- ЧИТАЙТЕ ЗВ'ЯЗАНО, якщо транзакції бачать лише скоєні дані, але можуть виникнути невідповідності, коли дві транзакції можуть переходити на пальці один одного
- ПОВТОРЕННЕ ЧИТАТИ, коли вирішується один вид непослідовності, не повторюваного читання
- СЕРІАЛІЗАЛЬНІ, що гарантує існування певного віртуального порядку, в якому здійснення транзакцій призведе до результатів, до яких призвело їх виконання
Однак стандарт SQL має підхід, заснований на блокуванні, для цих невідповідностей баз даних, і з міркувань продуктивності багато баз даних використовують підхід, заснований на знімку знімків, який має такі рівні:
- ЧИТАЙТЕ ЗВ'ЯЗАНО, що саме в блокуванні баз даних
- ІЗОЛЯЦІЯ СНАПШОТУ, де база даних бачить знімок усіх даних, і якщо вона намагається оновити рядок, який був оновлений якоюсь іншою транзакцією, її скасовують, але все ж є деякі відомі аномалії, які можуть мати місце
- СЕРІАЛІЗАЦІЙНА, яка є такою ж, як і в блокуванні баз даних, але цього разу реалізується по-іншому, не беручи блокування, а забезпечуючи відсутність порушень серіалізації, і якщо таке порушення виявлено, скасовуючи транзакцію
Скасування транзакцій у цих базах даних на основі ізоляції знімків може виглядати занепокоєнням, але потім знову кожна база даних скасуватиме транзакцію через тупик, тому будь-яка розумна програма все одно повинна мати можливість повторно спробувати транзакцію.
Ви хочете - рівень ІРІАЛІЗАЦІЙНОГО ізоляції: це забезпечує, якщо транзакції, виконані незалежно одна за одною, призводять до хорошого стану, будь-яке паралельне виконання транзакцій також призводить до хорошого стану. На щастя, Майкл Кейхіл у своїй докторській дисертації з’ясував, як рівень ізоляції СЕРІАЛІЗАЦІЙНО може бути підтриманий за допомогою знімків ізольованих баз даних з невеликими зусиллями.
Якщо використовувати рівень ізоляції СЕРІАЛІЗАЦІЙНОГО МОЖЛИВОСТІ у базі даних, що базується на знімку, якщо двоє людей одночасно намагаються запустити збережену процедуру, і вони будуть наступати на пальці ніг, одна з транзакцій буде скасована.
Тепер, чи справді SQL Server підтримує рівень ізоляції СЕРІАЛІЗАЦІЙНОГО (замість маскування ізоляції знімків за ключовим словом СЕРІАЛІЗАБІЛЬНІ )? Відверто кажучи, я не знаю: єдина база даних, яку я знаю, що підтримує її - це PostgreSQL.
Незважаючи на те, що мені не вдалося дати конкретних порад SQL Server, я все-таки публікую цю відповідь, оскільки користувачі PostgreSQL та користувачі інших баз даних, які можуть розглянути можливість переходу на PostgreSQL, можуть отримати користь від моєї відповіді. Також користувачі баз даних не PostgreSQL, які не можуть перейти на PostgreSQL, можуть тиснути на свого улюбленого постачальника баз даних, щоб запропонувати справжній рівень ІРІАЛІЗАЦІЙНОЇ ізоляції.