Не сме сами, част 2
Oct 28th, 2009 by yavor
Дублирането на данни е много неприятно. То може да доведе до всякакви грешни резултати. Това, че се случва произволно, го направи и трудно за елиминиране (ако няма някакъв естествен ключ в данните). Така приходите на фирмата може да излязат 120 000, вместо 115 000. По-лошо: това може да се случи и с разходите
Но много по-тежка е ситуацията със загубата на данни. Това е в общи линии най-лошото, което може да се случи на една информационна система. Ако работи бавно - това се оправя (викате ме и ви казвам как
), ако не е удобна за потребителите - също, ако не си върши работата - доработва се. Но ако има загуба на данни, оправията е много по-трудна, понякога и невъзможна.
Ето и една весела процедура, която освен до дублиране, може до доведе и до загуба на данни:
-
CREATE OR REPLACE PROCEDURE Process_New_Data IS
-
– example code - has a BUG!!!
-
BEGIN
-
– 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;
Тук забавлението настава така:
Сесия 1 прехвърля (много) данни с insert-select. Това, естествено, отнема време
Сесия 2 зарежда още един (или няколко няколко) batch в loader таблицата. Естествено, те са с processed = 0
Сесия 1 завършва с прехвърлянето и изтрива всички редове, които са били маркирани като не-прехвърлени (включително и новопостъпилите)
В този случай няма никакво значение къде ще сложите commit. И след всеки ред да има commit, пак няма да се избегне загубата на данни.