Дек. 172009
 

(към част 3)

Основно правило при многопотребителската работа е да си заключваш ресурсите, с които работиш. Едно здраво заключване може да спести много главоболия. За съжаление за да направиш добро заключване, трябва 1) да си осъзнал, че ти трябва, и 2) да знаеш как да го направиш 🙂

Повечето хора се сещат за select ... for update. Обаче има и други заключваници, които могат да помогнат на съвестния db developer. Единият вариант е Lock table. Ще използвам примера от част 2:

create or replace procedure Process_New_Data is
  -- example code - not scalable!!!
begin
  -- lock the log table, so none will be able to add/remove batches
  lock table batch_log in exclusive mode;
  -- process the loaded batches
  insert /*+append*/
  into prod_table
    select -- do some processing
           batch_id, get_something(column1, column2), calculate_something(column3, column4),
           RANK() over(PARTITION BY column5, column6 order by column7) rn, 
           column8, column9, ...
      from loader_table
     where batch_id in (select batch_id
                          from batch_log
                         where processed = 0);

  -- delete the rows from loader table
  delete from loader_table
   where batch_id in (select batch_id
                        from batch_log
                       where processed = 0);

  -- mark the batches as processed
  update batch_log
     set processed = 1
   where processed = 0;

  commit;
end;

В случая още в началото на процедурата заключваме таблицата batch_log. Това означава, че никой няма да може да добавя, променя или премахва редове от нея. :
– ако има сесия, която вкарва нови данни, при опит да направи insert – ще чака.
– ако има друга сесия, която изпълнява нашата процедура за обработка/преместване на данни – ще гръмне или ще чака, в зависимост от това дали ще дадем wait на заключването. Това е и една от причините този lock да се прави в самото начало, преди да сме свършили някаква друга работа.

Самото заключване се „отключва“ автоматично в с първия commit или rollback. За това точно този подход е неприложим в ситуации като описаната в част 1.

По-лошото е, че този подход е адски не-скалируем. Това е brute force на защитата. Докато не приключим с всичката работа, никой няма да може да работи по тази таблица (освен да select-ва). С други думи, заменили сме един проблем с друг. И сега проблема ще се прояви при натоварване с конкурентни сесии. Може да се каже, че сме по-добре: проблемът ще е ясен, няма да има случайни загуби или дублиране. Но си е проблем.

Интересна дилема: колкото повече (и по-рестриктивни) заключваници използваме, толкова по-зле понася товар едно приложение. Но ако не ги използваме, добрата саклируемост води до грешни данни. Някой да си е помислил, че има просто решение? 🙂

(към част 5)

 Posted by at 11:54

Sorry, the comment form is closed at this time.