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ł?
transakcje w funkcji
- Rejestracja: dni
- Ostatnio: dni
- Postów: 7923
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ąć
- Rejestracja: dni
- Ostatnio: dni
- Postów: 114
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)
- Rejestracja: dni
- Ostatnio: dni
- Postów: 7923
tak, ale nic nie stoi na przeszkodzie, żeby wykonał się pierwszy a drugi nie
- Rejestracja: dni
- Ostatnio: dni
- Postów: 114
Da się zrobić, żeby jeśli się drugi nie wykona to pierwszy się cofnie?
- Rejestracja: dni
- Ostatnio: dni
- Postów: 7923
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ę.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 114
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?
- Rejestracja: dni
- Ostatnio: dni
- Postów: 7923
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
- Rejestracja: dni
- Ostatnio: dni
- Postów: 3079
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ą.