Блокування із низьким рівнем деталізації (шаблон проєктування): відмінності між версіями

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до навігації Перейти до пошуку
[неперевірена версія][неперевірена версія]
Вилучено вміст Додано вміст
Goo3Bot (обговорення | внесок)
м дивіться також -> див. також
InternetArchiveBot (обговорення | внесок)
Виправлено джерел: 1; позначено як недійсні: 0.) #IABot (v2.0.8.7
Рядок 74: Рядок 74:


== Джерела ==
== Джерела ==
* [https://martinfowler.com/eaaCatalog/coarseGrainedLock.html Coarse Grained Lock]
* [https://martinfowler.com/eaaCatalog/coarseGrainedLock.html Coarse Grained Lock] {{Webarchive|url=https://web.archive.org/web/20201209061456/https://martinfowler.com/eaaCatalog/coarseGrainedLock.html |date=9 грудня 2020 }}


{{Шаблони проєктування ПЗ}}
{{Шаблони проєктування ПЗ}}

Версія за 16:33, 29 травня 2022

Блокування із низьким рівнем деталізації (англ. Coarse Grained Lock) — шаблон проєктування, який пропонує блокувати групу об'єктів за допомогою єдиного елементу блокування.

Опис

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

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

Реалізація

Щоб реалізувати блокування із низьким рівнем деталізації необхідно створити єдину точку конкуренції на право доступу до групи заблокованих елементів. Як приклад, таким об'єктом може виступати корінь агрегації.

class Customer 
{
    public int Id { get; set; }
    public string Name { get; set; }

    public Address Address { get; set; }
    public void ChangeAddress(string newAddressName)
    {
        this.Address.Name = newAddressName;
    }
}

class Address
{
    public string Name { get; set; }
}

public void ChangeCustomerAddress(int customerId, string newAddress)
{
    _lockService.AcquireLock(customerId.ToString());

    Customer customer = db.GetCustomerAggregate(customerId);
    customer.ChangeAddress(newAddress);
    
    db.Update(customer);

    _lockService.ReleaseLock(customerId.ToString());
}

Іншою спільною точкою блокування може бути, наприклад, номер версії:

// деякий маркер для групи об'єктів
// підходить як для оптимістичного, так і для песимістичного блокування
class Version 
{
    public Guid VersionId { get; set; }
}
class Customer 
{
    public int Id { get; set; }
    public string Name { get; set; }

    public Address Address { get; set; }
    public Version Version { get; set; }
}

class Address
{
    public string Name { get; set; }
    public Version Version { get; set; }
}

Див. також

Джерела