Окт. 282009
 

(към част 2)

Един малко по-добър вариант изглежда така:

– В началото вземаме текущата дата
– Когато избираме кои данни да обработим, освен processed=0 гледаме и датата на зареждане – да е по-малка от датата за начало на обработката, която се запомнили
– когато изтриваме обработените данни от loader таблицата, отново изтриваме само тези, които са „заредени“ преди началото на обработката

Процедурата би изглеждала така:

create or replace procedure Process_New_Data2 is
  -- example code - has a BUG!!!
  transfer_date date;
begin
  -- get the time when we start the transfer
  transfer_date := sysdate;

  -- 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 load_time < transfer_date -- get only the batches loaded before we start
                           and processed = 0);

  -- delete the rows from loader table
  delete from loader_table
   where batch_id in (select batch_id
                        from batch_log
                       where load_time < transfer_date -- delete only the batches loaded before we start
                         and processed = 0);

  -- mark the batches as processed
  update batch_log
     set processed = 1
   where load_time < transfer_date -- mark only the batches loaded before we start
     and processed = 0;

  commit;
end;

За съжаление това отново не е гарантирано решение. Шанса за загуба на данни тук е много по-малък, но не е нулев, и много зависи от метода на зареждане на нови данни.

Проблема се изразявана едно ниво по-дълбоко: някоя сесия може да е заредила данни преди няколко секунди (може и минути), но да не е commit-нала промените. Съответно нашият inser-select няма да ги хване, но докато върви той, другата сесия има достатъчно време да направи commit и няколко милиона реда да се появят за малко, докато delete-а не ги изтрие безславно.

(към част 4)

 Posted by at 13:55

Sorry, the comment form is closed at this time.