Повторне запитання від:
/programming/129329/optimistic-vs-pessimistic-locking
Скопіюйте / вставте відповідь із наведеного вище посилання:
Оптимістичне блокування - це стратегія, коли ви читаєте запис, враховуєте номер версії та переконайтеся, що версія не змінилася перед тим, як записати запис назад. Коли ви пишете запис назад, ви фільтруєте оновлення на версію, щоб переконатися, що вона атомна. (тобто не оновлювався між періодами, коли ви перевіряєте версію і записуєте запис на диск) та оновлюєте версію одним зверненням.
Якщо запис забруднений (тобто інша ваша версія), ви перериваєте транзакцію, і користувач може її повторно запустити.
Ця стратегія найбільш застосовна для систем з високим обсягом і трирівневої архітектури, де вам не обов'язково підтримувати з'єднання з базою даних для вашого сеансу. У цій ситуації клієнт насправді не може підтримувати блокування баз даних, оскільки з'єднання взяті з пулу, і ви, можливо, не використовуєте одне і те ж з'єднання від одного доступу до іншого.
Песимістичне блокування - це коли ви блокуєте запис для виключного використання, поки не закінчите з ним. Він має набагато кращу цілісність, ніж оптимістичне блокування, але вимагає бути обережним з дизайном програми, щоб уникнути тупиків. Для використання песимістичного блокування вам потрібно або безпосередньо підключитись до бази даних (як це зазвичай відбувається у дворівневому застосуванні клієнтського сервера) або зовнішньо доступний ідентифікатор транзакції, який можна використовувати незалежно від з'єднання.
В останньому випадку ви відкриваєте транзакцію з TxID і потім знову підключаєтесь за допомогою цього ідентифікатора. СУБД підтримує блокування та дозволяє вибирати сеанс резервного копіювання через TxID. Ось так працюють розподілені транзакції за допомогою двофазних протоколів фіксації (наприклад, транзакцій XA або COM +).
Змінити (Додавання додаткової інформації для вирішення питання про ефективність):
Ефективність залежить від вашого оточення. Візьміть до уваги наступні фактори:
Ви знаєте, що оптимістично буде краще завдяки одночасності в більшості ситуацій. Залежно від RDBMS та середовища це може бути менш ефективним. Зазвичай при оптимістичному блокуванні ви виявите, що значення потрібно десь перетворювати на рядки.
Наприклад, з MS SQL Server він переміщується до TempDB, а в кінці стовпця додається щось між 12-14 байтами. Увімкнення оптимістичного блокування з рівнем ізоляції, таким як Snapshot Isolation, може спричинити фрагментацію, і ваш коефіцієнт заповнення потрібно буде скорегувати, оскільки рядки тепер мають додаткові дані в кінці, що може призвести до того, що сторінка буде майже повною, і це призведе до розбиття сторінки, яка знизиться. ваше виконання. Якщо ваш TempDB недостатньо оптимізований, це буде не так швидко.
Тож я думаю, що контрольний список такий:
- -У вас є достатньо IO / ресурсів для обробки форми версій версій? Якщо ні, то ви додаєте накладні витрати. Якщо так, то якщо ви читаєте дані часто, поки ви часто блокуєте їх для запису, ви помітите гарне поліпшення одночасності в режимі читання і запису (хоча запис все ще блокує запис, читання більше не блокує запис і навпаки)
- -Чи ваш код чутливий до тупиків або у вас виникає блокування? Якщо ви не відчуваєте довгих блокувань або багато тупиків, то додаткові накладні витрати оптимістичного блокування не призведуть до того, що все буде швидше, звичайно, у більшості випадків ми тут говоримо мілісекунди.
- -Якщо ваша база даних велика (або на обмеженому рівні обладнання), і ваші сторінки даних майже наповнені, залежно від RDBMS, ви можете викликати розбиття основних сторінок і фрагментацію даних, тому обов'язково врахуйте переіндексацію після включення.
Це мої думки з цього питання, відкриті для того, щоб почути більше від громади.