Witam,
Napisałem procedurę składowaną w PL/pgSQL wywoływaną z poziomu JDBC, która dokonuje dwóch insertów i jeden update.
- Kazdy watek ma wlasne polaczenie JDBC.
- Polecenie jest wykonywane przez SELECT nazwa_procedury_skladowanej_z_parametrami(?);.
Procedura jest wywoływana przez 50 działających jednocześnie wątków, na tym samym rekordzie tabeli (update). Jest to test na deadlocki i błedy trasakcji, sytuaja malo prawdpodobna w praktyce, stworzona na potrzeby testow. Są dwa możliwe scenariusze:
a) ponieważ procedura składowana jest transakcyjna operacja daje spodziewany wynik
b) operacja konczy sie zakleszczeniem operacji: rzadko ale zawsze
CREATE OR REPLACE FUNCTION recv_product_from_user(bigint, bigint, integer, timestamp without time zone)
RETURNS void AS
$BODY$
DECLARE
BEGIN
IF $3 <= 0 THEN
RAISE EXCEPTION 'number of products must be greater than zero';
END IF;
-- copy state of the product to the history table: product_datetime_state
INSERT INTO product_datetime_state (id_product, num_available, prd_datetime)
SELECT p.id_product, p.num_available, (SELECT $4 ) FROM product p WHERE p.id_product = $2;
-- add new delivery to product_recv
INSERT INTO product_recv (id_product, id_user, num_recv, datetime) VALUES ($2, $1, $3, $4);
-- update product state (number of current items available)
UPDATE product p SET num_available = num_available + $3 WHERE p.id_product = $2;
END;
$BODY$
W jaki sposob zabezpieczyc sie przed deadlockiem powstajacym podczas wykonywania procedury UPDATE?
Pozdrawiam,