Перейти до вмісту

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

Матеріал з Вікіпедії — вільної енциклопедії.

Блокування із низьким рівнем деталізації (англ. 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; }
}

Див. також

[ред. | ред. код]

Джерела

[ред. | ред. код]