|
Тема |
Re: Синхронзация при вмъкване [re: мopaв] |
|
Автор |
salle (един такъв) |
|
Публикувано | 21.11.05 13:51 |
|
|
Наистина ти убягват основни понятия. Което не е лошо защото самият факт, че си задаваш тези въпроси означава, че имаш желание да разбереш за какво иде реч.
Това с което се сблъскваш е т.нар. Разрешаване на Конфликти (Conflict Resolution) - обширна област с различни подходи към нея.
Едно от най-базовите неща в СУБД е т.нар. Първичен Ключ (Primary Key). По дефиниция ПК е уникален идентификатор на реда. Когато имаш дефиниран ПК (а теорията изисква всяка таблица да има дефиниран ПК) то СУБД се грижи в ПК да няма дублирани стойности.
Ето ти я и първата стъпка. да речем че имаш таблица Фактури с колонка Номер. По закон Номерът на фактурата трябва да е уникален и съответно дефинираш ПК върху тази колонка.
Оттук нататък ако една сесия вмъкне ред с номер 1234 СУБД ще върне грешка при всеки опит да се вмъкне същия ред.
Какво се случва в твоя пример? Ами първият печели, следващите трябва да повторят упражнението отначало.
В много случаи това е достатъчно. Самият факт обаче, че дадена сесия трябва да повтаря едни и същи неща е проблем. Особено при голямо натоварване.
На всичкото отгоре обикновено с вмъкването на един ред се променя съдържанието и на други таблици.
Следващият въпрос е как де се минимизират подобни конфликти.
И тук вече нещата се решават по разнообразни начини. Ето някои съществени неща:
1) Заключване: Всяка СУБД има механизъм за заключване на определени ресурси. Идеята е както на много други места в програмирането (файловите системир POSIX mutex и т.н.)
Заключването бива явно и неявно а също така Споделено (Shared lock, S-Lock) и Изключително (Exclusive liock, X-Lock)
Частен случай: Заключваш таблицата за писане т.е. казваш на всички останали сесии "Не пипай!!! Може да гледаш но не и да променяш" после си свършваш работата и отключваш.
Втората и другите сесии се опитват да заключат същата таблица и чакат ключалката да се освободи. Проблемът е решен с подреждане на опашка. Между другото това е известно като "Песимистичен подход"
2) Транзакционен модел с поддръжка на много версии и "Оптимистичен подход".
Самият термин Транзакция е повод огромен обем от теория и практика.
При оптимистичния подход на две и повече транзакции се позволява да добавят едни и същи неща тъй като по дефиниция Транзакциите работят изолирано една от друга - всяка може да "вижда" свое собствено копие на данните. Идеята е когато Транзакциите приключат успешно с COMMIT (търси ACID transactions) СУБД да се опита да разеши възникналия конфликт.
Двата подхода Песимистичния и Оптимистичния си имат своите предиства и недостатъци - в различни ситуации всеки от тях може да има огромно предимство пред другия.
Може ли обаче конфликтът да се избегне вместо да се опитваме да го разрешим пост фактум?
Понякога гоже и за това се грижат генераторите на стойности. Тук вече започваш силно да зависиш от конкретната СУБД.
По разбираеми причини ще ти дам пример с MySQL.
В MySQL можеш да дефинираш т.нар. AUTO_INCREMENT колонка. Пример:
CREATE TABLE example (id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, name CHAR(16));
MySQL се грижи при вмъкване на нов ред да генерира нова стойност.
Подходът тук е първо вмъкваш ред който побучава гарантирано уникална стойност на id, след това проверяваш какво стойност си вмъкнал и я използваш за останалата част от работата.
INSERT INTO example (name) VALUES('Гошо');
SELECT LAST_INSERT_ID();
Функцията LAST_INSERT_ID(); ще върне стойността на id за реда вмъкнат от текущата сесия дори и ако междувременно други сесии са вмъкнали нови редове.
Не случайно обаче ти дадох пример с фактури. Проблемът при подхода с автоматично генерирани стойности е, че се получават "дупки" а данъчните ще ти отрежат главата ако им кажеш, че номерацията на фактурите ти не е непрекъсната.
Дупки се получават защото дадена сесия може да се откаже от въпросните данни на по-късен етап. В терминологията на транзакциите - може да се наложи да се направи ROLLBACK до начално състояние.
Тъй, че автоматично генерираните стойности не винаги вършат работа.
Изобщо добре дошъл в чудния свят на СУБД където има един универсален отговор на всички въпроси:
- Зависи!
|
| |
|
|
|