powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / could not serialize access due to concurrent update
10 сообщений из 10, страница 1 из 1
could not serialize access due to concurrent update
    #39493892
Michael Ponomarev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем привет,

в существующем java приложении периодически получаем Subj. Согласно документации postgre это может быть из-за Serializable уровня изоляции транзакции.

что-есть: postgresql 9.3
триггер на таблице, который вызывает хранимую процедуру.

Собственно error:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
Internal Exception: org.postgresql.util.PSQLException: ERROR: could not serialize access due to concurrent update
  Where: SQL statement "WITH upsertquery AS ( 
		UPDATE vehicle_state_log
		SET
		  vehstl_cc_modified_date = now(),
		  vehstl_cc_modified_by = p_cc_modified_by,
		  vehstl_vehicle_id = COALESCE(p_vehicle_id, vehstl_vehicle_id),
		  vehstl_latitude = COALESCE(p_latitude, vehstl_latitude),
		  vehstl_longitude = COALESCE(p_longitude, vehstl_longitude),
		  vehstl_heading = COALESCE(p_heading, vehstl_heading),
		  vehstl_speed = COALESCE(p_speed, vehstl_speed),
		  vehstl_position_timestamp = COALESCE(p_position_timestamp, vehstl_position_timestamp),
		  vehstl_curr_driver_id = COALESCE(p_curr_driver_id, vehstl_curr_driver_id),
		  vehstl_curr_driver_login = COALESCE(p_curr_driver_login, vehstl_curr_driver_login),
		  vehstl_curr_driver_logout = COALESCE(p_curr_driver_logout, vehstl_curr_driver_logout),
		  vehstl_issues = COALESCE(p_issues::boolean, vehstl_issues),
		  vehstl_issues_timestamp = COALESCE(p_issues_timestamp, vehstl_issues_timestamp),
		  vehstl_ignition_on = COALESCE(p_ignition_on::boolean, vehstl_ignition_on),
		  vehstl_ignition_on_timestamp = COALESCE(p_ignition_on_timestamp, vehstl_ignition_on_timestamp)
		WHERE vehstl_id = v_vehstl_id
	RETURNING *
	) 
	INSERT INTO lg_vehicle_state_log (
	  	vehstl_id,
	  	vehstl_cc_created_date,
	  	vehstl_vehicle_id,
	  	vehstl_latitude,
	  	vehstl_longitude,
	  	vehstl_heading,
	  	vehstl_speed,
	  	vehstl_position_timestamp,
	  	vehstl_curr_driver_id,
	  	vehstl_curr_driver_login,
	  	vehstl_curr_driver_logout,
	  	vehstl_issues,
	  	vehstl_issues_timestamp,
	  	vehstl_ignition_on,
	  	vehstl_ignition_on_timestamp
    		) 
	SELECT 
	  	v_vehstl_id,
	  	now(),
	  	p_vehicle_id,
	  	p_latitude,
	  	p_longitude,
	  	p_heading,
	  	p_speed,
	  	p_position_timestamp,
	  	p_curr_driver_id,
	  	p_curr_driver_login,
	  	p_curr_driver_logout,
	  	p_issues::boolean,
	  	p_issues_timestamp,
	  	p_ignition_on::boolean,
	  	p_ignition_on_timestamp	
	WHERE NOT EXISTS (SELECT * FROM upsertquery)"
PL/pgSQL function fill_vehicle_state_log(character varying,bigint,double precision,double precision,double precision,double precision,timestamp without time zone,bigint,timestamp without time zone,timestamp without time zone,character,timestamp without time zone,character,timestamp without time zone) line 45 at SQL statement
SQL statement "SELECT fill_vehicle_state_log('trg_cc_remoteeq_position_air', v_vehicle_id, NEW.pos_latitude,
	  NEW.pos_longitude, NEW.pos_heading, v_speed, v_vlog_timestamp, NULL, NULL, NULL, NULL,
	  NULL, NULL, NULL)"
PL/pgSQL function fun_cc_remoteeq_position_air() line 11 at PERFORM
Error Code: 0
Call: INSERT INTO CC_REMOTEEQ_POSITION (POS_ID, POS_ALTITUDE, POS_CC_CREATED_DATE, POS_HEADING, POS_LATITUDE, POS_LOG_ID, POS_LONGITUDE, POS_CC_MODIFIED_DATE, POS_CC_MODIFIED_BY, POS_ADDRESS_ID) VALUES (4567610, NULL, {ts '2017-07-14 02:02:23.341'}, NULL, 34.0410006, 4598626, -117.6174944, {ts '2017-07-14 02:02:23.341'}, 'RodsData', NULL) 




что смущает:
след код внутри хранимки:
Код: plsql
1.
LOCK TABLE lg_vehicle_state_log IN SHARE ROW EXCLUSIVE MODE;



Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
bla-bla
...
     BEGIN
	LOCK TABLE lg_vehicle_state_log IN SHARE ROW EXCLUSIVE MODE;
	WITH upsertquery AS ( 
		UPDATE lg_vehicle_state_log
		SET
		  vehstl_cc_modified_date = now(),
		  vehstl_cc_modified_by = p_cc_modified_by,
		  vehstl_vehicle_id = COALESCE(p_vehicle_id, vehstl_vehicle_id),
		  vehstl_latitude = COALESCE(p_latitude, vehstl_latitude),
		  vehstl_longitude = COALESCE(p_longitude, vehstl_longitude),
		  vehstl_heading = COALESCE(p_heading, vehstl_heading),
		  vehstl_speed = COALESCE(p_speed, vehstl_speed),
		  vehstl_position_timestamp = COALESCE(p_position_timestamp, vehstl_position_timestamp),
		  vehstl_curr_driver_id = COALESCE(p_curr_driver_id, vehstl_curr_driver_id),
		  vehstl_curr_driver_login = COALESCE(p_curr_driver_login, vehstl_curr_driver_login),
		  vehstl_curr_driver_logout = COALESCE(p_curr_driver_logout, vehstl_curr_driver_logout),
		  vehstl_issues = COALESCE(p_issues::boolean, vehstl_issues),
		  vehstl_issues_timestamp = COALESCE(p_issues_timestamp, vehstl_issues_timestamp),
		  vehstl_ignition_on = COALESCE(p_ignition_on::boolean, vehstl_ignition_on),
		  vehstl_ignition_on_timestamp = COALESCE(p_ignition_on_timestamp, vehstl_ignition_on_timestamp)
		WHERE vehstl_id = v_vehstl_id
	RETURNING *
	) 
	INSERT INTO lg_vehicle_state_log (
	  	vehstl_id,
	  	vehstl_cc_created_date,
	  	vehstl_vehicle_id,
	  	vehstl_latitude,
	  	vehstl_longitude,
	  	vehstl_heading,
	  	vehstl_speed,
	  	vehstl_position_timestamp,
	  	vehstl_curr_driver_id,
	  	vehstl_curr_driver_login,
	  	vehstl_curr_driver_logout,
	  	vehstl_issues,
	  	vehstl_issues_timestamp,
	  	vehstl_ignition_on,
	  	vehstl_ignition_on_timestamp
    		) 
	SELECT 
	  	v_vehstl_id,
	  	now(),
	  	p_vehicle_id,
	  	p_latitude,
	  	p_longitude,
	  	p_heading,
	  	p_speed,
	  	p_position_timestamp,
	  	p_curr_driver_id,
	  	p_curr_driver_login,
	  	p_curr_driver_logout,
	  	p_issues::boolean,
	  	p_issues_timestamp,
	  	p_ignition_on::boolean,
	  	p_ignition_on_timestamp	
	WHERE NOT EXISTS (SELECT * FROM upsertquery);
     END;



собственно вопрос: может ли причиной ошибки быть не уровень из-изоляции транзакции (потому что судя по коду везде READ COMMITTED), а именно лок таблицы + эмуляция upsert ?
...
Рейтинг: 0 / 0
could not serialize access due to concurrent update
    #39494204
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Michael Ponomarev,

а _fdw табличек у вас тут нигде нет ? а то там повышение уровня изоляции как--то наблюдалось. на внешней стороне.
...
Рейтинг: 0 / 0
could not serialize access due to concurrent update
    #39494205
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Michael Ponomarev,

и да, вы по коду прилады судите ? или тупо в хранимки зырите ?
...
Рейтинг: 0 / 0
could not serialize access due to concurrent update
    #39494483
Michael Ponomarev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwq,

что такое _fdw не знаю

1. про транзакции сужу по java коду
2. смущает вот что:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
CREATE OR REPLACE FUNCTION fill_vehicle_state_log(
...параметры
DECLARE
...переменные
BEGIN
... какой-то код
... зачем опять BEGIN - вложенная транзакция? и тогда почему нет COMMIT???
     BEGIN
	LOCK TABLE lg_vehicle_state_log IN SHARE ROW EXCLUSIVE MODE;
	WITH upsertquery AS ( 
		UPDATE lg_vehicle_state_log
		SET
		  vehstl_cc_modified_date = now(),
                  ... остальные поля
        WHERE vehstl_id = v_vehstl_id
	RETURNING *
	) 
	INSERT INTO lg_vehicle_state_log (
	  	vehstl_id,
                ... остальные поля
    		) 
	SELECT 
	  	v_vehstl_id,
                .. остальные поля
	WHERE NOT EXISTS (SELECT * FROM upsertquery);
     END;
END
$PSP$ LANGUAGE plpgsql;
...
Рейтинг: 0 / 0
could not serialize access due to concurrent update
    #39494628
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Michael Ponomarev,

какая ять вложенная транзакция в plpgsql ?

вы давно с дуба падали ?
...
Рейтинг: 0 / 0
could not serialize access due to concurrent update
    #39494649
Michael Ponomarev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwq,

люблю sql.ru

https://www.postgresql.org/docs/9.3/static/sql-begin.html

это получается к plpgsql не применимо ?
...
Рейтинг: 0 / 0
could not serialize access due to concurrent update
    #39494685
Author the new one
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Michael Ponomarev,

Получается да.
В plpgsql есть только неявные savepoint'ы

https://www.postgresql.org/docs/9.6/static/plpgsql-control-structures.html#PLPGSQL-ERROR-TRAPPING
"When an error is caught by an EXCEPTION clause, the local variables of the PL/pgSQL function remain as they were when the error occurred, but all changes to persistent database state within the block are rolled back."

qwwq, тоже обратите на это внимание.

По основному вопросу: обрабатывайте также, как и дедлок; если сильно досаждает, то можно переписать.
...
Рейтинг: 0 / 0
could not serialize access due to concurrent update
    #39494792
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Michael Ponomarevqwwq,

люблю sql.ru

https://www.postgresql.org/docs/9.3/static/sql-begin.html

это получается к plpgsql не применимо ? больше того -- со словцом "вложенные" оно не применимо даже в постгрессовском SQL
ибо никаких вложенных транзакций в пж не существует.
существует идеология savepoint
в плпгскл она [идеология savepoint] неявно присутствует в виде блоков plpgsql {BEGIN ..... EXCEPTION WHEN .... END;} где бегин и являет собой сейвпойнт на случай обрабатываемых исключений.

Код: sql
1.
show transaction_isolation;



или дерните из приложения перед вашей хранимочкой ещё и

Код: sql
1.
SELECT * FROM pg_settings  WHERE name IN ('transaction_isolation','default_transaction_isolation')

-- почитаете
можно в нотификацию RAISE {NOTICE|WARNING} вывести прямо из хранимки -- в логах найдёте.
...
Рейтинг: 0 / 0
could not serialize access due to concurrent update
    #39494842
Павел Лузанов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Michael Ponomarevqwwq,

люблю sql.ru

https://www.postgresql.org/docs/9.3/static/sql-begin.html

это получается к plpgsql не применимо ?
Вы не в том месте читаете документацию:
It is important not to confuse the use of BEGIN/END for grouping statements in PL/pgSQL with the similarly-named SQL commands for transaction control. PL/pgSQL's BEGIN/END are only for grouping; they do not start or end a transaction.

https://www.postgresql.org/docs/9.6/static/plpgsql-structure.html
...
Рейтинг: 0 / 0
could not serialize access due to concurrent update
    #39494863
Michael Ponomarev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Павел Лузанов,

Спасибо, а то уже вера в здравый смысл пошатнулась.
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / could not serialize access due to concurrent update
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]