Předmět Autor Datum
Sql si tabulky uzamyká sám, ale jde o to že někdy když se posílá větší množství dat a dojde ke koliz…
William 11.05.2007 10:00
William
Jakým způsobem byla tabulka "uzamčena"?
Jan Fiala 11.05.2007 10:03
Jan Fiala
Posílám data vzdáleně, tzn. spustím nějak uloženou proceduru která zpracovává pomocí transakcí určit…
William 11.05.2007 10:07
William
Pokud by mel zahodit nezpracovana data, bylo by treba zpracovavat je v cyklu po castech (po zaznamu)…
Jan Fiala 11.05.2007 10:17
Jan Fiala
Vždy se provádí úprava maximálně nad třeba tabulkama v jedné transakci, těch transakcí mám několik.…
William 11.05.2007 10:46
William
Tobe nevadi, ze když to spadne, tak to v tabulkach tabulka1 a tabulka2 zapsáno bude a v #xp_results_…
Jan Fiala 11.05.2007 11:25
Jan Fiala
No mám to rozdělené na cykly, pokud jeden uzel projde, druhý neprojde, při příštím spojení to projde…
William 11.05.2007 11:38
William
V prvnim cyklu jsou 2 tranakce za sebou, pokud mi neunikly nejake BEGIN-END Pokud se prvni provede a…
Jan Fiala 11.05.2007 11:45
Jan Fiala
Chtěl jsem to udělat pokud možno tak aby se provádělo co nejmíň operací v jedné transakci, aby při p…
William 11.05.2007 11:47
William
No je to něco jako asi takto, to co jsem vypsal je jen část : Pokud 1.transakce proběhne úspěšně, pr…
William 11.05.2007 11:57
William
Osobně bych to řešil takto: V cyklu (nebo bez něj) bych si vše zpracoval do pomocnych tabulek bez tr…
Jan Fiala 11.05.2007 12:28
Jan Fiala
To by se dalo jenomže já potřebuju ještě než data vložím do tabulky rozhodnout o tom jestli ty data…
William 11.05.2007 13:54
William
Tak nakonec jsem to částečně zafixoval. Jednak jsem zvýšil lock_timeout a všiml jsem si že nemám nai… poslední
William 12.05.2007 00:01
William

Sql si tabulky uzamyká sám, ale jde o to že někdy když se posílá větší množství dat a dojde ke kolizi zůstane tabulka uzamčená několik minut, používám transakce, a v transakcích rollback. Nejspíš to způsobuje on, že při neúspěchu operace trvá dlouhodou dobu než to vrátí do původního stavu.

Posílám data vzdáleně, tzn. spustím nějak uloženou proceduru která zpracovává pomocí transakcí určité úlohy nad tabulkami. Pokud dojde k přístupu jiného connections na uzamčenou tabulku, mám nastavený LOCK_TIMEOUT 1000, tak někdy dojde ke kolizi, tam právě dojde k rollbacku. Sql mi pak zahlásí : Lock request time out period exceeded. Chci aby pokud dojde ke kolizi, aby ty data které ještě nezpracoval aby je zahodil a ty které už provedl aby nechal tak. Nevím jestli když v transakci dám pokud nenastane chyba aby byl commit tran a pokud dojde k chybě aby se nestalo nic.

Vždy se provádí úprava maximálně nad třeba tabulkama v jedné transakci, těch transakcí mám několik.
Něco jako toto :
DECLARE ZMENY CURSOR
KEYSET
FOR SELECT UDALOST, OBJE_ID_POMOCNE, OBJE_ID
FROM tabulka

OPEN ZMENY
FETCH NEXT FROM ZMENY INTO @UDALOST, @OBJE_ID_POMOCNE, @OBJE_ID ´
WHILE (@@fetch_status <> -1)
BEGIN

BEGIN TRAN

INSERT INTO [tabulka1]
([UZIVATEL], [OBJE_ID_POMOCNE], [OBJE_ID])
SELECT @UDALOST, @OBJE_ID_POMOCNE, @OBJE_ID

INSERT INTO [tabulka2]
([UZIVATEL], [OBJE_ID_POMOCNE], [OBJE_ID])
SELECT @UDALOST, @OBJE_ID_POMOCNE, @OBJE_ID

IF (@@ERROR <> 0)
BEGIN
ROLLBACK TRAN
END
ELSE
BEGIN
COMMIT TRAN
END

BEGIN TRAN

INSERT INTO #xp_results_polo
EXEC [Everend2006].[dbo].[SQL_SQL] @OBJE_ID
SET @ID_OBJE_OBJE = (SELECT TOP 1 ID FROM #xp_results_polo)

IF (@@ERROR <> 0)
BEGIN
ROLLBACK TRAN
END
ELSE
BEGIN
IF @ID_OBJE_OBJE > 0
BEGIN
COMMIT TRAN
END
ELSE
BEGIN
ROLLBACK TRAN
END
END

FETCH NEXT FROM ZMENY INTO @UDALOST,@OBJE_ID_POMOCNE
END
CLOSE ZMENY
DEALLOCATE ZMENY

No mám to rozdělené na cykly, pokud jeden uzel projde, druhý neprojde, při příštím spojení to projde co se provedlo a co ne. Takže pokud první transakce při zápisu do tabulky 1,2 projde a spadne to u druhé transakce, nevadí to. Dřív jsem to měl jako že ve velké transakci, takže tyto dvě byli vnořené. Ale to my přišlo že to není asi moc dobré.

Chtěl jsem to udělat pokud možno tak aby se provádělo co nejmíň operací v jedné transakci, aby při případné chybě trval rollback co nejkratší dobu.
Je pravda že cursor je dost pomalý ale zatím jsem nepřišel na jeho náhradu.
Dejme tomu že cursor prochází tabulku ve které je zhruba tak 100 záznamů.
Stejně mi nejde narozum, proč se to uzamkne na tak dlouhou dobu jakou je třeba 5 minut.
Možná tam mám něco špatně zapsané.
V jednu chvíli pracuje nad stejnýma tabulkama tak maximálně deset uživatelů.

No je to něco jako asi takto, to co jsem vypsal je jen část :
Pokud 1.transakce proběhne úspěšně, provádí se 2.transakce, pokud druhá uspěje provádí se 3.transakce.
Pokud 1.transakce proběhne úspěšně, provádí se 2.transakce, pokud druhá neuspěje, dojde k rollbacku 2.transakce, první zůstavá vyřízená, 3.transakce se už neprovede.

Osobně bych to řešil takto:
V cyklu (nebo bez něj) bych si vše zpracoval do pomocnych tabulek bez transakce.
Jakmile bych měl připravena data pri insert, zahájím transakci, nasypu najednou pomoi INSERT INTO - SELECT ... data z pomocnych tabulek do ostrych a transakci ukončím. Pokud jde o stovky záznamů, musí to být hotové během chviličky.

To by se dalo jenomže já potřebuju ještě než data vložím do tabulky rozhodnout o tom jestli ty data do tabulky můžu uložit, jedná se o skladové zásoby, tzn. kontroluju jestli množství nepřesahuje dovolenou mez, pak taky kontroluju nedělitelné množství. Takže to je problém. A že bych počítal kolik množství daného zboží obsahuje dávka a pak to kontroloval oproti dané mezi, to asi taky není dobré. A navíc dávka neobsahuje jenom příkaz insert, ale taky update a delete.

Tak nakonec jsem to částečně zafixoval. Jednak jsem zvýšil lock_timeout a všiml jsem si že nemám naindexovanou jednu tabulku ze které čtu a ve které je nějakých 40000 řádků. Takže po těchto dvou úpravách když už dojde k hlášce lock request out of period, zámek se během sekundy uvolní.

Zpět do poradny Odpovědět na původní otázku Nahoru