Неявне блокування (шаблон проєктування) — Вікіпедія
Неявне блокування (англ. Implicit Lock) — шаблон проєктування, який пропонує винести блокування на глобальний рівень.
Опис[ред. | ред. код]
Будь-яка схема блокування корисна лише в тому випадку, якщо в ній не зроблено "проколів". Якщо забути накласти блокування, тоді вся схема блокування є марною. Якщо забути звільнити ресурс, він буде заблокований, що приведе до погіршення продуктивності аплікації. Застосування блокування запису, замість блокування читання призведе до використання застарілих даних, а невірне використання версії — до небажаних змін даних іншим користувачем. Окрім цього, механізм паралельного доступу важко тестувати через, що помилки в блокуванні можуть бути не замічені в тестах.
Щоб уникнути помилок розробників під час накладання блокування, даний шаблон пропонує винести блокування на глобальний рівень. Таким чином, можна один раз описати логіку блокування, яка буде застосовуватись до усіх транзакцій у системі (чи лише до необхідних), або ж скористатись вбудованим механізмом, що пропонує фреймворк.
Реалізація[ред. | ред. код]
Реалізуємо неявне блокування за допомогою декораторів. Головна їх перевага, в тому, що об'єкт до яких вони застосовуються навіть не підозрює про зміни у своїй функціональності.
interface IUserRepository { User GetUser(int id); } class UserRepository : IUserRepository { public User GetUser(int id) { return db.Users.Find(id); } } class ConcurrentUserRepository : IUserRepository { public User GetUser(int id) { // оскільки в межах сеансу може відбуватись пошук одного і того самого об'єкту декілька разів // перевіряємо чи у сеансу вже є блокування на даний ресурс LockKey lockKey = LockKey.Build(_appSessionManager.GetSessionId(), id.ToString()); _lockService.AcquireLock(lockKey); try { return _userRepository.GetUser(id); } finally { _lockService.ReleaseLock(lockKey); } } }
Тоді при використанні сервісу ми не задумуватимемось про блокування.
var userRepository = new ConcurrentUserRepository(new UserRepository()); // ресурс неявно блокується var user = userRepository.GetUser(19);
Див. також[ред. | ред. код]
Джерела[ред. | ред. код]
- Implicit Lock [Архівовано 26 листопада 2020 у Wayback Machine.]