Szemafor T-SQL-ben
Egy szép napon szembesültem azzal a problémával, hogy alkalmazásszerverek párhuzamos futásuk közben vágják egymás alatt a fát. Az alkalmazások módosítása kicsit fájdalmas lett volna, ezért SQL oldalon kezeltük le a problémát. A kritikus szakaszban egyszerre csak egyvalaki lehet – ezt szokták szemaforral biztosítani. Na, ez történt itt is, csak T-SQL-ben szemaforoztam. Érdekes élmény:
-- SQL 2005 - alapvetően a try-catch-re építünk WHILE 1 = 1 BEGIN BEGIN TRY CREATE TABLE ##semaphor (a int); BREAK; END TRY BEGIN CATCH WAITFOR DELAY '000:00:03'; CONTINUE; END CATCH END -- Itt a kritikus szakasz DROP TABLE ##semaphor
A gondolatmenet egyszerű: van egy globális temptábla (a dupla rácsos linzer jelzi, hogy ezt bárki elérheti, nemcsak a létrehozója), ami a szemafor. Aki létrehozta, az beléphet a kritikus szakaszba, a többiek meg egy helyben ugrálnak, és próbálják létrehozni a táblát. Ennyi.
Felvetődik a kérdés, hogy mi van azzal, aki SQL 2000-t futtat még. Az egyrészt upgrade-elhet :), másrészt pedig használhatja a következő scriptet:
-- SQL 2000-ben az object_id a barátunk
WHILE object_id('tempdb..##semaphor') is not null
BEGIN
WAITFOR DELAY '000:00:03'
END
CREATE TABLE ##semaphor (a int)
-- Itt a kritikus szakasz
DROP TABLE ##semaphor
Mivel a SQL 2000-ben még nincs try-catch, teljesen más logikával kell hozzáállnom: lekérdezem az object_id-ját a temptáblának, ha létezik, akkor várok, ha nem, akkor megcsinálom. Egyetlen gyenge pontja az előzőhöz képest: ha egyszerre ketten látják úgy, hogy nincs ott a temptábla, és megpróbálják létrehozni, akkor az egyik sikerül, a másik pedig elszáll egy szép exception-nel, mert már létezik a tábla. Ezt sajnos nem bírtam lekezelni. Egyébként meglepően gyakran fordul elő ez az eset ahhzo képest, hogy mennyire kicsinek tűnik a valószínűsége.

Leave a comment