Wyczytałem w necie, że postgresql nie wspiera transakcji zagnieżdżonych we funkcji, i po kilku próbach faktycznie nie wspiera. I teraz moje pytanie, jak się zabezpieczyć, żeby np. jeśli jeden update się z jakiegoś powodu nie wykona to, żeby ten drugi też się nie wykonał?
chodzi Ci o stored proc? Jeśli tak to jak wysypie się insert to wysypie się cała procedura przecież i będziesz wiedział czy zakomitować czy cofnąć
Hmm... Nie wiem czy w postgresie to się nazywa stored proc :D w mysql na pewno
CREATE OR REPLACE FUNCTION public.test()
RETURNS integer AS
$body$
BEGIN
UPDATE cos SET cos = 1 WHERE cos2 = 1;
UPDATE cos2 SET cos = 1 WHERE cos2 = 1;
RETURN 0;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
i wywołanie
SELECT test();
i teraz jak się z jakiegoś powodu nie wykona pierwszy update to drugi się też nie wykona, ta? (2 dni w postgresie to nie wiem :D)
tak, ale nic nie stoi na przeszkodzie, żeby wykonał się pierwszy a drugi nie
Da się zrobić, żeby jeśli się drugi nie wykona to pierwszy się cofnie?
jak gdzieś wpiszesz SELECT test();
i potem to uruchomisz to będziesz widział czy się wykonało czy był błąd. Na tej podstawie albo zatwierdzisz albo cofniesz. Każda zmiana w bazie jest objęta transakcją, z tym że transakcja może być rozpoczęta niejawnie ale zakończona (commit/roolback) musi być jawnie przez usera. Jaśniej nie potrafię.
Nie dokońca zrozumiałem kiedy się zaczyna ta niejawna transakcja. Więc w php w ciągu jednej sesji odpale sobie to "SELECT test();" i sprawdze czy nie było błędu, jak był błąd to robię "ROLLBACK;", czy mam przed odpaleniem test() rozpacząc jawna transakcje?
Nie pamiętam czy transakcja jest rozpoczynana zaraz po połączeniu czy dopiero po pierwszej operacji DML. W każdym razie jak zrobisz commit/rollback to jest kończona bieżąca i rozpoczynana nowa albo od razu albo po operacji DML i tak aż do końca trwania połączenia. Jest to niejako transakcja domyślna. Możesz w każdej chwili rozpocząć jawnie nową transakcję a następnie ją zakończyć. Nie potrafię tego jaśniej wytłumaczyć.
Co do jawnego rozpoczynani i kończenia transakcji jest to o wiele czytelniejsze i jasno "daje do zrozumienia", że dany kawałek albo się zapisuje cały albo w ogóle
Funkcja w PostgreSQL jest sama w sobie transakcją, tzn. jeżeli nie wykona się część funkcji to nie wykona się cała funkcja. PostgreSQL nie wspiera transakcji zagnieżdżonych, więc nie można dodatkowo umieścić transakcji w funkcji, która już jest transakcją.