Error while committing the transaction postgresql

Обсуждение: ERROR : invalid transaction termination : PostgreSQL v12 ERROR : invalid transaction termination : PostgreSQL v12 CREATE OR REPLACE PROCEDURE TEST_TRANSACTION()LANGUAGE ‘plpgsql’ SECURITY DEFINERAS $BODY$DECLARE G_LAST_UPDATE_USER_SYSTEM VARCHAR2(6) := ‘SYSTEM’; G_LAST_UPDATE_MODULE_BATCH VARCHAR2(5) := ‘BATCH’; G_CNTR_LOADING_EXPIRED TMS_CONTAINER_LOADING.STATUS_CODE%TYPE := ’90’; G_DG_MANIFEST_DELETED TMS_DG_MANIFEST.STATUS_CODE%TYPE := ’80’; G_DG_MANIFEST_COMPLETED TMS_DG_MANIFEST.STATUS_CODE%TYPE := ’95’; v_num_day numeric; v_batch_count numeric; v_log_count numeric := 0; […]

Содержание

  1. Обсуждение: ERROR : invalid transaction termination : PostgreSQL v12
  2. ERROR : invalid transaction termination : PostgreSQL v12
  3. Re: ERROR : invalid transaction termination : PostgreSQL v12
  4. Обсуждение: ERROR : invalid transaction termination : PostgreSQL v12
  5. ERROR : invalid transaction termination : PostgreSQL v12
  6. Re: ERROR : invalid transaction termination : PostgreSQL v12
  7. Re: ERROR : invalid transaction termination : PostgreSQL v12
  8. Типичные ошибки при работе с PostgreSQL. Часть 2

Обсуждение: ERROR : invalid transaction termination : PostgreSQL v12

ERROR : invalid transaction termination : PostgreSQL v12

CREATE OR REPLACE PROCEDURE TEST_TRANSACTION(
)
LANGUAGE ‘plpgsql’
SECURITY DEFINER
AS $BODY$
DECLARE
G_LAST_UPDATE_USER_SYSTEM VARCHAR2(6) := ‘SYSTEM’;
G_LAST_UPDATE_MODULE_BATCH VARCHAR2(5) := ‘BATCH’;

G_CNTR_LOADING_EXPIRED TMS_CONTAINER_LOADING.STATUS_CODE%TYPE := ’90’;
G_DG_MANIFEST_DELETED TMS_DG_MANIFEST.STATUS_CODE%TYPE := ’80’;
G_DG_MANIFEST_COMPLETED TMS_DG_MANIFEST.STATUS_CODE%TYPE := ’95’;

v_num_day numeric;
v_batch_count numeric;
v_log_count numeric := 0;
v_local_batch_count numeric;
BEGIN
v_batch_count := 0;
LOOP
update tms_container_loading
set status_code = G_CNTR_LOADING_EXPIRED
, last_update_tm = clock_timestamp()::timestamp(0)
, last_update_user_an = G_LAST_UPDATE_USER_SYSTEM
, last_update_module_code = G_LAST_UPDATE_MODULE_BATCH
where tms$vvd.is_vessel_departed(vessel_visit_c,trunc(clock_timestamp()::timestamp(0))) = 1
and coalesce(status_code,’

‘) <> G_CNTR_LOADING_EXPIRED and ctid in (select a.ctid from tms_container_loading where tms$vvd.is_vessel_departed(vessel_visit_c,trunc(clock_timestamp()::timestamp(0))) = 1
and coalesce(status_code,’

‘) <> G_CNTR_LOADING_EXPIRED LIMIT 20000);
EXIT WHEN NOT FOUND; /* apply on SQL */
GET DIAGNOSTICS v_local_batch_count = ROW_COUNT; v_batch_count := v_batch_count + v_local_batch_count;
COMMIT;
END LOOP;
v_log_count := v_log_count + 1; CALL Log(v_batch_count,’TMS_CONTAINER_LOADING’,NULL, ‘TMS$BATCH_JOB’, v_log_count);
COMMIT;
END;
$BODY$;

Re: ERROR : invalid transaction termination : PostgreSQL v12

What is the point of COMMITting after a few records? Why not let the whole batch run through. If there are any errors, PostgreSQL will rollback the whole transaction anyway.

As opposed to Oracle, PostgreSQL won’t commit some records, while others failed within the same transaction. As soon as a single operation within a transaction fails, it’s dead and all subsequent operations will fail.

CREATE OR REPLACE PROCEDURE TEST_TRANSACTION(
)
LANGUAGE ‘plpgsql’
SECURITY DEFINER
AS $BODY$
DECLARE
G_LAST_UPDATE_USER_SYSTEM VARCHAR2(6) := ‘SYSTEM’;
G_LAST_UPDATE_MODULE_BATCH VARCHAR2(5) := ‘BATCH’;

G_CNTR_LOADING_EXPIRED TMS_CONTAINER_LOADING.STATUS_CODE%TYPE := ’90’;
G_DG_MANIFEST_DELETED TMS_DG_MANIFEST.STATUS_CODE%TYPE := ’80’;
G_DG_MANIFEST_COMPLETED TMS_DG_MANIFEST.STATUS_CODE%TYPE := ’95’;

v_num_day numeric;
v_batch_count numeric;
v_log_count numeric := 0;
v_local_batch_count numeric;
BEGIN
v_batch_count := 0;
LOOP
update tms_container_loading
set status_code = G_CNTR_LOADING_EXPIRED
, last_update_tm = clock_timestamp()::timestamp(0)
, last_update_user_an = G_LAST_UPDATE_USER_SYSTEM
, last_update_module_code = G_LAST_UPDATE_MODULE_BATCH
where tms$vvd.is_vessel_departed(vessel_visit_c,trunc(clock_timestamp()::timestamp(0))) = 1
and coalesce(status_code,’

‘) <> G_CNTR_LOADING_EXPIRED and ctid in (select a.ctid from tms_container_loading where tms$vvd.is_vessel_departed(vessel_visit_c,trunc(clock_timestamp()::timestamp(0))) = 1
and coalesce(status_code,’

‘) <> G_CNTR_LOADING_EXPIRED LIMIT 20000);
EXIT WHEN NOT FOUND; /* apply on SQL */
GET DIAGNOSTICS v_local_batch_count = ROW_COUNT; v_batch_count := v_batch_count + v_local_batch_count;
COMMIT;
END LOOP;
v_log_count := v_log_count + 1; CALL Log(v_batch_count,’TMS_CONTAINER_LOADING’,NULL, ‘TMS$BATCH_JOB’, v_log_count);
COMMIT;
END;
$BODY$;

Источник

Обсуждение: ERROR : invalid transaction termination : PostgreSQL v12

ERROR : invalid transaction termination : PostgreSQL v12

CREATE OR REPLACE PROCEDURE TEST_TRANSACTION(
)
LANGUAGE ‘plpgsql’
SECURITY DEFINER
AS $BODY$
DECLARE
G_LAST_UPDATE_USER_SYSTEM VARCHAR2(6) := ‘SYSTEM’;
G_LAST_UPDATE_MODULE_BATCH VARCHAR2(5) := ‘BATCH’;

G_CNTR_LOADING_EXPIRED TMS_CONTAINER_LOADING.STATUS_CODE%TYPE := ’90’;
G_DG_MANIFEST_DELETED TMS_DG_MANIFEST.STATUS_CODE%TYPE := ’80’;
G_DG_MANIFEST_COMPLETED TMS_DG_MANIFEST.STATUS_CODE%TYPE := ’95’;

v_num_day numeric;
v_batch_count numeric;
v_log_count numeric := 0;
v_local_batch_count numeric;
BEGIN
v_batch_count := 0;
LOOP
update tms_container_loading
set status_code = G_CNTR_LOADING_EXPIRED
, last_update_tm = clock_timestamp()::timestamp(0)
, last_update_user_an = G_LAST_UPDATE_USER_SYSTEM
, last_update_module_code = G_LAST_UPDATE_MODULE_BATCH
where tms$vvd.is_vessel_departed(vessel_visit_c,trunc(clock_timestamp()::timestamp(0))) = 1
and coalesce(status_code,’

‘) <> G_CNTR_LOADING_EXPIRED and ctid in (select a.ctid from tms_container_loading where tms$vvd.is_vessel_departed(vessel_visit_c,trunc(clock_timestamp()::timestamp(0))) = 1
and coalesce(status_code,’

‘) <> G_CNTR_LOADING_EXPIRED LIMIT 20000);
EXIT WHEN NOT FOUND; /* apply on SQL */
GET DIAGNOSTICS v_local_batch_count = ROW_COUNT; v_batch_count := v_batch_count + v_local_batch_count;
COMMIT;
END LOOP;
v_log_count := v_log_count + 1; CALL Log(v_batch_count,’TMS_CONTAINER_LOADING’,NULL, ‘TMS$BATCH_JOB’, v_log_count);
COMMIT;
END;
$BODY$;

Re: ERROR : invalid transaction termination : PostgreSQL v12

Re: ERROR : invalid transaction termination : PostgreSQL v12

On 11/23/20 12:36 AM, Jagmohan Kaintura wrote:
> Hi Team,
>
> We have many BATCH JOBS in Oracle which we are committing after
> processing few Records. These batch Jobs process in some subsets and
> call transaction control statements COMMIT in case of Success and
> ROLLBACK in case of failure.
>
> While converting to POstgreSQL we converted in Same Format with COMMIT
> and ROLLBACK. But while executing it ended up with below error message.
> ERROR: invalid transaction termination
> CONTEXT: PL/pgSQL function inline_code_block line 29 at COMMIT
>
> While reviewing the Transaction Management in PostgreSQL
> «https://www.postgresql.org/docs/12/plpgsql-transactions.html
> » it
> speaks about a format which is not Supported.
>
> Transaction control is only possible in |CALL| or |DO| invocations from
> the top level or nested |CALL| or |DO| invocations without any other
> intervening command. For example, if the call stack is |CALL proc1()| →
> |CALL proc2()| → |CALL proc3()|, then the second and third procedures
> can perform transaction control actions. But if the call stack is |CALL
> proc1()| → |SELECT func2()| → |CALL proc3()|, then the last procedure
> cannot do transaction control, because of the |SELECT| in between.
>
> My Call has : CALL Batch Job => SELECT function Used in SQL Statements
> ==> Call Procedure. We have transaction control in «CALL Batch Job» only.
>
> Pseudo Code is like : Highlighted in BOLD is a function call. It’s
> failing when getting executed as we are using functions into this procedure.
> *Can any help on this matter , how I can implement Batch Jobs as we
> wanted to commit in few intervals of 20000 records ?*
> We can’t remove this function from the statement as its value is
> dependent on column value.
>
> CREATE OR REPLACE PROCEDURE TEST_TRANSACTION(
> )
> LANGUAGE ‘plpgsql’
> SECURITY DEFINER
> AS $BODY$
> DECLARE
> G_LAST_UPDATE_USER_SYSTEM VARCHAR2(6) := ‘SYSTEM’;
> G_LAST_UPDATE_MODULE_BATCH VARCHAR2(5) := ‘BATCH’;
>
> G_CNTR_LOADING_EXPIRED TMS_CONTAINER_LOADING.STATUS_CODE%TYPE := ’90’;
> G_DG_MANIFEST_DELETED TMS_DG_MANIFEST.STATUS_CODE%TYPE := ’80’;
> G_DG_MANIFEST_COMPLETED TMS_DG_MANIFEST.STATUS_CODE%TYPE := ’95’;
>
> v_num_day numeric;
> v_batch_count numeric;
> v_log_count numeric := 0;
> v_local_batch_count numeric;
> BEGIN
> v_batch_count := 0;
> LOOP
> update tms_container_loading
> set status_code = G_CNTR_LOADING_EXPIRED
> , last_update_tm = clock_timestamp()::timestamp(0)
> , last_update_user_an = G_LAST_UPDATE_USER_SYSTEM
> , last_update_module_code = G_LAST_UPDATE_MODULE_BATCH
> where
> *tms$vvd.is_vessel_departed(vessel_visit_c,trunc(clock_timestamp()::timestamp(0)))*
> = 1
> and coalesce(status_code,’

‘) <> G_CNTR_LOADING_EXPIRED
> and ctid in (select a.ctid from tms_container_loading where
> *tms$vvd.is_vessel_departed(vessel_visit_c,trunc(clock_timestamp()::timestamp(0)))*
> = 1
> and coalesce(status_code,’

‘) <> G_CNTR_LOADING_EXPIRED
> LIMIT 20000);
> EXIT WHEN NOT FOUND; /* apply on SQL */
> GET DIAGNOSTICS v_local_batch_count = ROW_COUNT;
> v_batch_count := v_batch_count + v_local_batch_count;
> COMMIT;
> END LOOP;
> v_log_count := v_log_count + 1; CALL
> Log(v_batch_count,’TMS_CONTAINER_LOADING’,NULL, ‘TMS$BATCH_JOB’,
> v_log_count);
> COMMIT;
> END;
> $BODY$;

I’m still trying to figure out transaction management in procedures, so
bear with me. Not sure what the purpose of the second COMMIT is? Also
wonder if it is no the cause of the issue?

> —
> *Best Regards,*
> Jagmohan
> Senior Consultant, TecoreLabs.

Источник

Типичные ошибки при работе с PostgreSQL. Часть 2

Мы продолжаем публиковать видео и расшифровки лучших докладов с конференции PGConf.Russia 2019. В первой части доклада Ивана Фролкова речь шла о непоследовательном именовании, о constraints, о том, где лучше сосредоточить логику — в базе или в приложении. В этой части вас ждет разбор обработки ошибок, конкурентного доступа, неотменяемых операций, CTE и JSON.

Расскажу такую историю. Наш клиент говорит: «Медленно работает база, а наше приложение занимается обслуживаем населения. Мы боимся, что нас тут поднимут на вилы». Выяснилось, что у них было очень много процессов в состоянии idle in transaction. Приложение начало транзакцию, ничего не делает, но и транзакцию не завершает. Если вы взаимодействуете с какими-то внешними сервисами, то, в принципе, это нормальная ситуация. Другое дело, что если у вас состояние idle in transaction длится долго (больше минуты уже подозрительно), то это плохо потому, что PostgreSQL очень не любит долгие транзакции: VACUUM не сможет почистить все те строки, которые он мог бы увидеть, и долго висящая транзакция эффективно блокирует VACUUM. Начинают разбухать таблицы, индексы становятся всё менее эффективными.

В данном случае люди не вполне корректно писали запросы и получали декартовы произведения — такие запросы выполнялись по несколько дней. Ну а пользователь, он же нажмет кнопку, подождет результата и, если результата нет, снова нажмет кнопку.

Но это не объясняло, почему у них появляется столько процессов в idle in transaction. А появлялись они вот в какой ситуации: приложение лезет в базу, начинает транзакцию, лезет на какой-то внешний сервис, получает там ошибку, а дальше всё просто осыпается, печатаем в лог stack trace, и на этом успокаиваемся. Соединение остается заброшенным, висит и мешается.

Что с этим делать? Во-первых, надо обрабатывать ошибки всегда. Если к вам прилетела ошибка, пожалуйста, не игнорируйте ее. Хорошо еще, если PostgreSQL потерял соединение: он откатит транзакцию, переживём. На этом я еще остановлюсь. Ну а если есть код, который править совсем нет времени, то у нас еще есть max idle in transaction — можно поставить, и будет просто вышибать неактивные транзакции.

Типичный случай «обработки» ошибок: EXCEPTION WHEN OTHERS THAN NULL. Как-то мы спорили с коллегой о терминологии. Я говорил, что это переводится как «гори оно всё синим пламенем», а он — «пропади оно всё пропадом». Если у нас нечто плохое произошло, то, даже если всё с руганью осыпалось в лог, это всё же лучше, чем полная тишина — как здесь.

Если вы не знаете, что делать с ошибкой, то не надо ее и перехватывать. Очень распространенная практика: перехватили ошибку, записали в лог и побежали дальше, как будто ничего не произошло. Если вы, опять же, занимайтесь денежными операциями, и у вас произошла ошибка, которую вы проигнорировали, результаты могут быть непредсказуемые. В 90-е годы могли в лес, например, вывезти в багажнике. Сейчас времена помягче стали, но тоже мало приятного.

Если делаем операцию на клиенте, то, обычно, возвращаем значение: всё прошло удачно либо неудачно. И каждую ошибку обрабатываем. Я видел, как люди специально писали код plpgsql, где перехватывали ошибку, писали в лог, что, мол, да, была ошибка и довольно грубая, вставляли свой текст сообщения. Но SQLSTATE не возвращали. Это выполняется всегда, поэтому, если они забывали что-то проверить, то у них начинались проблемы.

Все, почему-то боятся исключений — как в plpgsql, так и в других языках. А если не придумывать что-то свое, а пользоваться стандартными возможностями языка, все обычно получается хорошо. Особенно эта проблема часто встречается, когда падает соединение. Оно упало, процесс idle in transaction, база заполняется, падает производительность. Между прочим, такая транзакция может еще оставить блокировки, но это, почему-то, встречается не так часто. Поэтому добавляйте в код обработки ошибки finally и там вычищайте соединение, отдавайте его обратно серверу.

Более того, в случае, если у вас хорошо, правильно поименованы constraint-ы, вы можете уже при обработке ошибки выкинуть исключение не из базы, а из приложения. В spring есть exception translation, в php, соответственно, set_exception_handler. Обратите внимание на те средства, которые вам предоставляет ваш фреймворк, они там неспроста появились.

Итак: не надо перехватывать ошибку, с которым не знаете что делать; именуйте ошибки тщательно и аккуратно; классифицируйте ошибки.

Лично я классифицирую по таким критериям: операцию можно повторить (например, у нас возник deadlock); операцию повторить нельзя, она уже выполнена; операция не может быть выполнена в принципе.

Как ни парадоксально, с точки зрения приложения, ситуации, когда возникнет deadlock, когда потеряно соединение и когда у нас кончились деньги для выплаты, — это ситуации одинаковые: обработчик ошибки попытается через некоторое время выполнить операцию снова.

С другой стороны, что пишут в приложении, в общем-то, не мое дело: я занимаюсь базой. Я лишь призываю аккуратно обрабатывать ошибки, иначе: idle in transaction, залоченные строки, пухнущие базы и так далее.

Большинство разработчиков считает, что они работают с базой одни, и их приложение выполняет операции строго последовательно. И это плюс всем реляционным СУБД потому, что, как ни странно, при этом всё работает, как правило, очень хорошо, даже со стандартным уровнем изоляции READ COMMITTED, а не SERIALIZABLE. В то же время, случаются ситуации, когда теряются обновления: один грузит форму, другой грузит эту же форму, один написал и сохранил, другой сохранил старую — изменения стерли. Первый пришел ругаться: «как же так, я столько написали, и всё потеряно».

Из моего опыта: раз в неделю по пятницам два менеджера проводили выплаты. Они должны
были меняться через раз, но, тем не менее, однажды полезли одновременно и сделали две выплаты на одного человека. Если у вас есть хоть какая-то возможность ошибки конкурентного доступа, она рано или поздно случится. Вопрос когда.

Кроме того, обращаю ваше внимание на ограничения. Я неоднократно видел, как уникальность пытались обеспечить триггерами. Сходу триггерами уникальность в таблице вы не обеспечите. Либо вам тогда нужно будет блокировать всю таблицу, либо делать еще какие-то сложные телодвижения. Вы рано или поздно на этом споткнетесь.

Пару раз натыкался на совершенно кошмарную вещь: из базы вызывается внешний web-сервис. Там проводились какие-то операции, изменяющие внешние сущности. Это плохо тем, что в базе транзакция может откатиться, но операции на удаленном сервисе откачены не будут.

Еще более тонкий момент — deadlock-и. Давайте представим: мы обрабатываем транзакцию, вызываем внешний web-сервис, что-то поменяли, после этого у нас возникнет deadlock, и мы откатываемся, потом пытаемся выполнить операцию еще раз, вызываем еще раз, при хорошем стечении обстоятельств еще раз возникает deadlock, опять откатываемся — так может
происходить много раз (я натыкался на пару сотен повторов). И вот вы обрабатываете эти deadlock-и более-менее корректно, повторяете операции и вдруг обнаруживаете, что уже в течении двух месяцев выплачиваете кому-то двойную сумму.

Я встречался с платежными сервисами, у которых был небогатый API: «выплатить такую-то сумму такому-то пользователю»; функция возвращает результат — выплачено / не выплачено. Во-первых, возникает проблема в случае повтора, во-вторых, непонятно, что делать, если прервалось соединение. Почему-то на эту тему тоже очень мало кто заморачивается.

На слайде пример: такая операция должна выполняться в два этапа: как бы предупреждение — «будем сейчас что-то делать»; сама операция.

Если мы вдруг прервёмся — мало ли, выключили питание — мы сможем повторно выполнить операцию. Если мы сдохли на втором этапе, то, по крайней мире, второй раз мы это не выполним, и это можно будет разобрать вручную. На самом деле подавляющее большинство таких операций нормально отрабатывает первый раз, но эти меры не теоретические измышления. Всё может нормально работать месяцами, и вдруг админ начинает мудрить с сетью, сервис начинает активно мигать — и начались проблемы.


На слайде 4 типа неотменяемых операций. Последний — неидемпотентные операции. Это совсем грустный случай. Я в начале говорил о товарище, который всё делал на триггерах именно чтобы обеспечить идемпотентность своих операций.


На конференции люди будут рассказать о Common Table Expressions, о том, как это хорошо. К сожалению, CTE в PostgreSQL не бесплатны: они требуют под себя work_mem. Если у вас выборка небольшая, то, в общем, ничего страшного. А если вдруг у вас она большая, то у вас начинаются проблемы. Люди очень часто используют CTE в качестве этаких мини-вьюшек — для того, чтобы можно было как-то структурировать приложение. CTE очень востребованные.

Можно сделать временные view, но, к сожалению, каждое занимает строчку в pg_class, и если это очень активно используется, то возможны проблемы с распуханием каталога.
В этом случае можно посоветовать сделать параметризированное view, либо динамически формировать запрос, но, к сожалению, в PostgreSQL изнутри с этим не очень здорово.

О JSON обычно рассказывают в превосходных тонах, но есть тенденция в приложении в JSON пихать вообще все что угодно. В принципе, всё работает неплохо. С другой стороны, из JSON-а данные достаются хоть и быстро, но не так быстро, как из колонок. Еще хуже, если у вас JSON большой, и его вынесло в TOAST. Чтобы JSON оттуда взять, его нужно поднять из TOAST-а.

Если все колонки в JSON-е, по ним даже построен функциональный индекс, то все равно оттуда доставать надо. Еще хуже получается при большом объеме, когда база большая, когда у вас bitmap index scan. Тогда у нас ссылки не на строки, а на целую страницу, и, для того, чтобы понять, что со страницы брать, PostgreSQL сделает Recheck, то есть он поднимает строчку из TOAST и проверяет, есть там это значение или нет, и соответственно уже пропускает или не пропускает. Если с небольшими колонками это работает хорошо, то с JSON это большая проблема. Слишком увлекаться JSON-ами не надо.

— Как проверять, когда со строкой работают несколько пользователей? Какие варианты есть?

— Во-первых, можно перед показом строки в форме вЫчитать значения всех колоночек и убедиться, что они не поменялись. Второй вариант, более удобный: высчитать хэш на всех
колонках, тем более, что колонки там могут быть большие и толстые. А хэш не такой большой.

— Вы говорите, что что надо именовать constraint-ы хорошими именами, чтобы пользователь мог понять, что происходит. Но есть ограничение в 60 символов на имя constraint-а. Этого часто не хватает. Как с этим бороться?

— Думаю, бороться самоограничением. В PostgreSQL это специальный тип длиной 64. В принципе можно перекомпилировать на бОльшую длину, но это не очень хорошо.

— В докладе вы заинтриговали нас тем, что нам надо делать что-то с архивами. Какой механизм вынесения устаревших данных в архив считается самым правильным?

— Как я в самом начале уже говорил, при должном усердии работает всё. Какой способ вам наболее удобен, тем и пользуйтесь.

Timing: 2-я часть доклада начинается с 25:16

— Есть некая процедура, которую вызывают параллельно несколько пользователей. Как ограничить параллельное выполнение этой процедуры, то есть выстроить всех
пользователей в очередь так, чтобы, пока один не закончит выполнение процедуры, следующий не мог начать ее использовать?

— Именно процедура? Или достаточно транзакции?

— Именно процедура, которая вызывается в некоторой транзакции.

— Вы можете поставить блокировку на объект. Были бы сложности, если б у вас было условие, скажем, не больше 3 одновременно. Но и это реализуемо. Я обычно использую транзакционные блокировки, но можно и внетранзакционные.

— Я бы хотела все-таки еще раз вернуться к архивным данным. Вы говорили о
возможности хранения архива так, чтобы из приложения данные были также доступны. Мне приходила в голову мысль просто сделать отдельную архивную базу. Какие еще есть варианты?

— Да, можно сделать архивную базу. Вы можете написать функцию и завернуть ее во вьюшечку. В функции вы можете творить всё, что в голову взбредет: можете в архивную базу ходить, можете поднимать с диска какие-то файлы, можете ходить к внешнему web-сервису, можете всё это комбинировать, можете сами какие-то случайные данные генерить — выбор ограничен только фантазией.

— К вопросу по поводу архивных данных: можно использовать партиции — новые фишки 11-й версии, когда делаем всю таблицу парционированной, а потом просто детачим партицию и оставляем ее как архив. К ней тоже можно осуществлять доступ.

— Конечно, почему бы нет. Уступаю место следующему докладчику.

Источник

HibernateSpatialJPA class:

 public class HibernateSpatialJPA {

    private static final EntityManagerFactory emFactory;
    static {
        try {
            emFactory = Persistence.createEntityManagerFactory("org.hibernate.events.jpa");
        }catch(Throwable ex){
            System.err.println("Cannot create EntityManagerFactory.");
            throw new ExceptionInInitializerError(ex);
        }
    }
    public static EntityManager createEntityManager() {
        return emFactory.createEntityManager();
    }

    public static void close(){
        emFactory.close();
    }
}

this is manager class:

 public class SavegeojsonManager {

    SavegeojsonEntity theEvent = new SavegeojsonEntity();

    public boolean insert(JSONObject json)
    {
        GeoJSON item = new GeoJSON(json);
        return insert(item);
    }

    public boolean insert(GeoJSON item)
    {
        boolean success=false;
        try {

            String vectorType = item.getType();
            EntityManager em = HibernateSpatialJPA.createEntityManager();
            em.getTransaction().begin();
            theEvent.setVectorType(vectorType);
            em.persist(theEvent);
            em.getTransaction().commit();
            em.close();
            success=true;
        }
        catch (Exception ex) {
            System.out.println(ex.getMessage());
            success = false;

        }
        HibernateSpatialJPA.close();
        return success;
    }
}

and this is GeoJsonClass :

   public class GeoJSON
{

    private int id;

    private String type;
    private String data;

    public int getId() { return id; }
    public void setId(int id) {  this.id = id; }

    public String getType() {return type;}
    public void setType(String type) {this.type = type;}

    public String getData() {return data;}
    public void setData(String data) { this.data = data; }

    public GeoJSON() {
    }

    public GeoJSON(JSONObject json) {
        parse(json);
    }


    public GeoJSON parse(JSONObject json) {
        StringWriter out = new StringWriter();
        json.write(out);
        this.data = out.toString();
        this.type = json.getString("type");

        try {
            out.close();
        } catch (IOException ex) {
            System.out.println(ex.getMessage());
            throw new RuntimeException(ex);
        }
        return this;
    }

}

But I am not able to save into database because error :

enter code here : «error while committing the transaction.»

Do you have any idea about this error ?

Below is the Exception stack trace:-

javax.persistence.RollbackException: Error while committing the transaction
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:92)
at com.springapp.model.SavegeojsonManager.insert(SavegeojsonManager.java:32)
at com.springapp.model.SavegeojsonManager.insert(SavegeojsonManager.java:19)
at com.springapp.mvc.HSpatialController.saveGeoJson(HSpatialController.java:46)
...
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: ERROR: column "vectortype" of relation "savegeojson" does not exist Position: 76 at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1377) at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1300) at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:80) ... 40 more Caused by: org.hibernate.exception.SQLGrammarException: ERROR: column "vectortype" of relation "savegeojson" does not exist Position: 76 at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:122) at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49) at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125) at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110) at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:129) at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81) at com.sun.proxy.$Proxy26.executeUpdate(Unknown Source) at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:56) at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2962) at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3403) at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:88) at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:362) at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:354) at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:275) at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:326) at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52) at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1214) at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:403) at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101) at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175) at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:75) ... 40 more Caused by: org.postgresql.util.PSQLException: ERROR: column "vectortype" of relation "savegeojson" does not exist Position: 76 at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2062) at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1795) at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257) at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:479) at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:367) at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:321) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122) ... 56 more

Вернуться в основную статью

Для облегчения поиска ошибок был создан отдельный раздел для сбора ошибок из АРМ ЭРС, читайте внимательнее подсказки ниже:


Для поиска по статье нажмите Ctrl+F и введите первые символы кода ошибки или вопроса

Поделиться статьей в:

  • Telegram
  • Vk

:!: В случае возникновения ошибки при отправке реестра: Невозможно отправить реестр талонов с периодом формирования, равным текущему месяцу

Причина:

Ошибка возникает из-за того, что реестр должен датироваться месяцем в котором он сформирован.

Решение:

Если вы отправляете реестр в начале месяца (например 1 января) то необходимо изменить дату реестра на 31 число предыдущего месяца (31 декабря), а дату формирования счета — текущий день календаря. НО ваш фонд может не принять данный реестр.

Также возможно стоит подождать решения ошибки от СФР или установить обновление ПО

Выдержка из чата СФР:

Реестры и счета за услуги декабря вы формируете январем в рамках договоров на 2022 год, не меняя срока действия договора. Создать в январе талоны за услуги, оказанные в декабре, система Фонда не позволяет. В случае талонов 1 и 3 будет продление периода оказания услуг по январь с формированием талонов в январе и предъявлении их на оплату в феврале. Проблема с талонами 2 решается с техподдержкой.


:!: В случае возникновения ошибки при получении результата обработки: Ошибка вызова сервиса передачи/получения данных VALID_SIGNATURE ЭП действительна; ERROR_BUILDING_CERT_PATH При проверке сертификата ЭП произошла ошибка. Ошибка построения цепочки сертификатов | INVALID_SIGNATURE ЭП недействительна. Обратитесь к разработчику программного обеспечения

Причина:

Ошибка возникает из-за нарушения корректности цепочки сертификатов — либо один из сертификатов цепочки просрочен, либо установлен не туда, либо это вообще некорректный сертификат.

Решение:

На рабочее место пользователя с 4.07.22 необходимо ставить в «Личное хранилище»:

  • Сертификат уполномоченного лица СФР

  • Сертификат ЛПУ (юр.лицо)

  • Сертификат руководителя ЛПУ (физ.лицо)

  • Сертификат главного бухгалтера

Скачиваем и устанавливаем ВСЮ ЦЕПОЧКУ СЕРТИФИКАТОВ уполномоченного лица ФСС:

Ссылка на скачивание

(eln_prod_Личное.cer устанавливаем в «Личное» остальные два в «Доверенные корневые центры сертификации»)

Убеждаемся что у пользователя есть права на контейнер закрытого ключа учреждения


:!: В случае возникновения ошибки при запуске программы: Unable to build entity manager factory

Причина:

Ошибка возникает в случае отсутствия связи с СУБД PostgreSQL, либо сервер БД недоступен

Решение

Необходимо проверить на сервере БД запущена ли служба Postgresql-9.5 и доступен ли сервер БД, а также порт указанный при установке АРМ ЭРС


:!: В случае возникновения ошибки при запуске программы «Invalid Configuration Location» The configuration area at .. could not be created. Please choose a writable location using the ‘-configuration’ command line option

Причина:

Пользователю недостаточно места для создания и хранения временных файлов, создаваемых программой.

Решение:

Проверьте квотирование места на диске: уберите квотирование либо увеличьте доступное пользователю пространство,


:!: В случае возникновения ошибки при получении результата обработки: Connection could not be allocated. Listener does not currently know of service requested in connect descriptor

Причина:

Сервер СФР временно не доступен

Решение:

Необходимо ожидать восстановления работоспособности


:!: В случае возникновения ошибки при получении результата обработки: Отсутствует уполномоченный представитель с таким сертификатом ЭП

Причина:

Выбран неправильный сертификат УЛ СФР

Решение:

Скачать сертификат Уполномоченного лица СФР отсюда: https://lk.fss.ru/cert.html установить его в личные и выбрать его в настройках подписи.


:!: В случае возникновения ошибки при получении результата обработки: Ошибка вызова сервиса передачи/получения данных. Could not send Message

Причина:

Сервер ФСС временно не доступен

Решение:

Необходимо ожидать восстановления работоспособности


:!: В случае возникновения ошибки при установке или обновлении программы «GostCryptography.dll Этому файлу не сопоставлена программа для выполнения этого действия»

Причина:

Возможно причина кроется в сломанных системных файлах

Решение:

Необходимо обновить систему и выполнить команды в командной строке от имени администратора:

sfc /scannow

и

DISM /Online /Cleanup-Image /RestoreHealth

После этого необходимо перезагрузиться

Подробнее вы можете прочитать здесь


:!: В случае возникновения «ошибки шифрования» при проставленной галочке
:

Причина:

Не применяются настройки шифрования выставленные в настройках ПО

Решение:

Перейти в «C:FssArmErsconfiguration.settings» (для х64 версии)

либо в «C:FssToolsconfiguration.settings» (для x86 версии)

Открыть в блокноте файл: ru.ibs.fss.eln.prefs
в конце добавить строчку
encryptmessages=1


:!: В случае возникновения «Internal Error COMCryptoAPIClient» :

Причина:

В процессе установки программы библиотека GostCryptography.dll по каким-то причинам не зарегистрировалась

Решение:

В командной строке CMD выполнить (с правами администратора):
Для x86 программы

cd C:FssTools
C:WindowsMicrosoft.NETFrameworkv4.0.30319RegAsm.exe /registered GostCryptography.dll 

Для x64 программы

cd C:FssArmErs
C:WindowsMicrosoft.NETFramework64v4.0.30319RegAsm.exe /registered GostCryptography.dll 

:!: В случае возникновения ошибок «Сообщение не найдено» либо бесконечный «Вызов сервиса ФСС» либо «Ошибка вызова сервиса передачи/получения данных Error processing request — getResultByID»

Причина:

Сервис СФР перегружен, либо некорректна подпись МО

Решение:

Необходимо повторить отправку/запрос позднее. В программе АРМ ЭРС проверьте в настройках подписи корректна ли подпись медицинской организации (МО) либо сертификат СФР


:!: В случае возникновения «Ошибки дешифрования сообщения. Ошибка при попытке расшифровать сообщение»


Причина:

Причиной возникновения данной ошибки может служить чрезмерная нагрузка на сервис СФР, либо сбой криптопровайдера

Решение:

Попробуйте совершить операцию позднее.

В крайнем случае проблема может решиться переустановкой криптопровайдера (КриптоПРО или VipnetCSP)

Также в программе АРМ ЭРС проверьте в настройках подписи корректна ли подпись медицинской организации (МО) либо сертификат СФР

После обновления ПО данная настройка может быть пустой

Также можно попробовать удалить все установленные сертификаты связанные с СФР и скачать их по данной ссылке:
https://disk.yandex.ru/d/nAQmOZ7WZi8S1w

(eln_prod_Личное.cer устанавливаем в «Личное» остальные два в «Доверенные корневые центры сертификации»)

Убеждаемся что у пользователя есть права на контейнер закрытого ключа учреждения

Также можно снять галочку на «Проверять подпись на входящих сообщениях»


:!: В случае возникновения ошибки «вызова сервиса передачи/получения данных. Зарегистрировано»

Причина:

Перебои в работе сервиса взаимодействия СФР, ваш запрос в очереди

Решение:

Ждать, совершить запрос позднее


:!: В случае возникновения ошибки «Отсутствует лицензия на осуществление медицинской деятельности»

Причина:

Текст ошибки говорит сам за себя

Решение:

Необходимо проверить введенные в настройках реквизиты организации а также связаться с региональным представителем СФР


:!: В случае возникновения ошибки «Отсутствует заключенный договор с ТОФ на оказание услуг»

Причина:

Текст ошибки говорит сам за себя

Решение:

Необходимо связаться с региональным представителем СФР


:!: В случае возникновения ошибки «Internal Error Rollback Exception» при попытке открыть сведения о посещениях

Причина:

Ошибка возникает из-за отсутствующих строках и колонках в БД, программа пытается прочитать данные в несуществующих ячейках

Решение:

Необходимо обновить ПО на рабочем месте, где установлена БД


:!: В случае возникновения ошибки «Unmarchalling Error» при попытке отправить/запросить талон/ЭРС

Причина:

скорее всего неправильно заполнены данные в определенном поле

Решение:

Необходимо изучить текст ошибки

(в данном примере ошибка гласит о том, что введено 10 цифр в поле, где должно быть 12 цифр)


:!: В случае возникновения ошибки «Invalid element in ErsOpenService .. -registerMODate» при попытке отправить/запросить ЭРС

Причина:

Вы используете устаревшую версию программы, введены новые контроли, поля и т.д.

Решение:

Необходимо обновить АРМ ЭРС


:!: В случае возникновения ошибки «ЭЦП неверна SIGNATURE ERROR ЭП Недействительна» при попытке отправить/запросить талон/ЭРС также возникает при запросе счета

Причина:

Внутренняя ошибка программы, из-за которой подпись на талоне не проставилась корректно

Решение:

Необходимо в талоне нажать кнопку «На подписании» затем снова подписать талон кнопкой «Подпись руководителя ЛПУ» (может потребоваться нажать 2 раза)

После этого повторно отправить талон


:!: В случае возникновения ошибки «В настройках соединения указан неправильный порт. Проверьте правильность адреса сервиса в настройках соединения» при попытке отправить/запросить талон/ЭРС

Причина:

Проблема связана с недоступностью (полной неработоспособностью сервиса СФР)

Решение:

Необходимо ожидать восстановления работоспособности сервиса


:!: В случае возникновения ошибки «Ошибка вызова сервиса передачи/получения данных. Несоответствующий статус для включения талонов в реестр» при попытке включить талоны в реестр

Причина:

Статус талонов в реестре отличается от «Принято в ТОФ»

Решение:

Для решения проблемы нужно убедиться, что статус перечисленных в ошибке талонов, включенных в реестр должен быть — Принято в ТОФ

Часто бывает так, что статус талона в локальной базе может отличаться от статуса в СФР (для этого можно запросить статус обработки повторно) можно уточнить этот момент у представителя СФР


:!: В случае возникновения ошибки «Дата постановки на учет должна быть равна началу периода наблюдения» при попытке сохранить ЭРС

Причина:

Дата постановки на учет была забита вручную и скорее всего неправильно

Решение:

Необходимо ввести одинаковую дату постановки на учет и дату начала периода наблюдения через кнопку «Календарь» в поле с датами


:!: В случае возникновения ошибки «Premature end of file»

Причина:

Ошибка возникает, когда валидация отправляемого XML-файла не проходит на удаленном сервисе. Проблема на стороне СФР.

Решение:

Ждать исправления


:!: В случае возникновения ошибки «Ошибка вызова сервиса передачи/получения данных. 1606: Несоответствующий статус для включения талонов в реестр: Талон» при попытке получить результат обработки счета

Причина:

Для счета не нужно запрашивать результат обработки

Решение:

Для решения проблемы необходимо нажать кнопку «Получить данные об оплате счета»


:!: В случае возникновения ошибки «Не удалось подписать информацию Invalid Iddata=[имя талона]» подписать реестр

Причина:

Некорректно заполнено поле — номер реестра

Решение:

Необходимо удалить пробелы или другие запрещенные символы из номера реестра


:!: В случае возникновения ошибки «The content of element ‘status’ is not complete.» при попытке запросить результат обработки

Причина:

Проблема на стороне сервиса взаимодействия с СФР

Решение:

Необходимо ждать решения проблемы со стороны СФР


:!: В случае возникновения ошибки Validator Exception: PKIX path validation failed: java.security.cert.CertPathValidatorException: timestamp check failed

Причина:

Проблема с SSL сертификатом на стороне СФР

Решение:

Необходимо обновить ПО, либо подсунуть файл из архива cacerts.zip

в папку с программой/jre/lib/security


:!: В случае возникновения ошибки «Internal error Widget is disposed»

Причина:

Внутренняя ошибка программы

Решение:

Перед любыми действиями делайте резервную копию папки!

Необходимо удалить содержимое папки

C:FssArmErsworkspace.metadata.pluginsorg.eclipse.e4.workbench

После этого перезапустите приложение


:!: В случае возникновения ошибки при отправке реестров «Ошибка вызова сервиса передачи/получения данных. Unmarshalling Error: Длина поля типа #AnonType_bankCheckingAccbillinfo не соответствует ограничению»

Причина:

Ограничение на минимальную длину обязательного поля для реквизитов банка в счете

Решение:

Убедитесь в корректности заполнения реквизитов банковского счета. Смотрите текст ошибки:

<bankCheckingAcc/> р/с минимум 20 символов
<bankName/> наименование банка минимум 4 символа
<bankBIK/> БИК банка минимум 6 символов

:!: В случае возникновения ошибки при сохранении и отправки счета «Ошибка при попытке сохранить данные в базу данных Error while committing the transaction»

Причина:

В схеме ers отсутствует столбец «final_price_fss» в таблице «fc_ers_check»

Решение:

Запускаем pgAdmin, открываем базу, переходим к схеме «ers»

Далее нажать на:

Качаем этот SQL-запрос и исполняем его в PgAdmin

Либо исполняем вручную данный запрос:

ALTER TABLE ers.fc_ers_check ADD COLUMN final_price_fss character varying(200);

UPDATE ers.fc_ers_check a
SET final_price_fss = (
	(	
		SELECT COALESCE(SUM(payment_sum::INTEGER), 0)
		FROM ers.fc_ers_payment
		WHERE id_check = a.id 
			AND (order_status = 1 OR order_status = 4)
	) - (
		SELECT COALESCE(SUM(payment_sum::INTEGER), 0)
		FROM ers.fc_ers_payment
		WHERE id_check = a.id 
			AND (order_status = 2 OR order_status = 3)
	)
)
WHERE a.id_check_state = 4;

UPDATE ers.fc_ers_check a
SET final_price_fss = ''
WHERE a.id_check_state != 4;

:!: В случае возникновения ошибки при попытке сохранить данные в базу данных «org.hibernate.HibernateException: More than one row with the given identifier was found: for class: ru.ibs.common.db.model.ers.FcErsTalon1»

Причина:

Появилась вторая строка в таблице «ers.fc_ers_talon1»

Решение:

Выполнить скрипт в PGAdmin:

delete from ers.fc_ers_talon1 where ers_num=номерэрс

После данного действия талон придется вводить заново.


:!: В случае возникновения ошибки The server selected protocol version TLS10 is not accepted by client preferences [TLS12]

Причина:

Версия протокола TLS на сервере отличается от версии TLS клиента

Решение:

Идем в папка_с_программой/jre/lib/security

Открываем файл java.security в блокноте

Ищем в нем строчку jdk.tls.disabledAlgorithms — удаляем tlsv1 и tlsv1.1

Сохраняемся


:!: В случае возникновения ошибки при попытке получить ЭРС из СФР — Error while commiting transaction. Invalid thread access

Причина:

Ошибка возникает из-за того, что реестр должен датироваться месяцем в котором он сформирован.

Решение:

Через консольный лог выясняем, в какую таблицу идёт ошибка записи, после чего через pgadmin исправляется значение соответствующей последовательности на max(ID) +1 из таблицы.

Пошагово:

находим нужное значение ID

Проставляем его в последовательности, не забыв прибавить единичку и сохраняем.

Выражаю благодарность за вклад в данный раздел пользователю: @Icosahedron

Всем, кому понравился или помог это проект — Вы можете помочь ему развиваться материально:
Donate (помощь проекту)

We have ran into a problem related to this thread. At this point I am not sure who these connections are coming from so I cannot ask them what exact changes they made to the default config, but I can duplicate the problem by changing the following in the config for my Postgres connection (I am running 22.0.0). I see above both of these settings have been referenced but I’d like to clarify a little to what exactly can happen on the database side because of changing them.

«Connection settings», «Initialization», uncheck Auto-commit.
AND
«Connection settings», «Metdata», Uncheck Open separate connection for metadata read.

I think info above explains what these do but I have not seen exact reference to the problem we experienced.

Once those 2 settings are changed simply connect to the database. Don’t do anything. I have enabled query logging on the database side to see what it runs and there are some metadata lookup queries. But the problem is the state the session is inside the database.

In pg_stat_activity the session state is «idle in transaction». I see people above have complained about this but that alone won’t really cause overall database problems unless you are automatically killing sessions in this state or something. Postgres considers a SELECT as a transaction so if you don’t autocommit and run a select you have an open transaction.

But the problem we see is in pg_stat_activity not only is that session state «idle in tranasction» but the backend_xmin column is populated. That is the key to our problem- getting column backend_xmin populated. And I cannot duplicate this issue connecting through psql, setting autocommit off, and runing the same series of queries/commands I see executed by DBeaver.

When autovacuum cleans up deleted rows from a table it can only clean up deleted records newer than the oldest backend_xmin across all database sessions- and that applies to every table in the database. Our scenario is we have a table that is very active from an update perspective (Postgres update is a delete/insert). So the table gets lots of deleted rows from these updates. The autovacuum process will normally keep up cleaning out these deleted rows. But we had an ad hoc session connected from DBeaver in this state where backend_xmin was populated just by them logging in. And then it sat there. For 5+ hours. So the number of uncleaned deleted rows in this table grew and grew and grew to over 200,000 which in turn caused queries hitting this table to have to read through more and more and more uncleaned up deleted rows. CPU on the server went from a consistent 15% utilization to over 50% utilization over this 5 hour period of time. For some reason the user closed their DBeaver session and CPU almost immediately went back to the 15% utilization because autovacuum was then able to clean up these deleted rows.

There is no way an application used to connect to a database should allow a user to click ANY options to be able to get a session in this state just by connecting to the database. I have no doubt whoever changed these default settings and connected to our database had no clue about the possible consequences of this. This is a huge red flag with this product. Again, this product should never allow a user to be able to change any type of configuration to get sessions into this state and I hope the developers of this product address this. It can be addressed however they want as long as a session connecting through DBeaver cannot select any options to get a session into this state just be connecting to the database- a state where their session has backend_xmin populated simply by connecting to the database.

Содержание

  1. Обсуждение: ERROR : invalid transaction termination : PostgreSQL v12
  2. ERROR : invalid transaction termination : PostgreSQL v12
  3. Re: ERROR : invalid transaction termination : PostgreSQL v12
  4. Недействительное завершение транзакции
  5. 1 ответ
  6. Thread: ERROR : invalid transaction termination : PostgreSQL v12
  7. ERROR : invalid transaction termination : PostgreSQL v12
  8. Re: ERROR : invalid transaction termination : PostgreSQL v12
  9. Please explain the inscrutable rules for when «commit» in a stored proc succeeds or causes a run-time error #1957
  10. Comments
  11. bllewell commented Aug 2, 2019 •
  12. Недействительное завершение транзакции
  13. 1 ответ

Обсуждение: ERROR : invalid transaction termination : PostgreSQL v12

ERROR : invalid transaction termination : PostgreSQL v12

CREATE OR REPLACE PROCEDURE TEST_TRANSACTION(
)
LANGUAGE ‘plpgsql’
SECURITY DEFINER
AS $BODY$
DECLARE
G_LAST_UPDATE_USER_SYSTEM VARCHAR2(6) := ‘SYSTEM’;
G_LAST_UPDATE_MODULE_BATCH VARCHAR2(5) := ‘BATCH’;

G_CNTR_LOADING_EXPIRED TMS_CONTAINER_LOADING.STATUS_CODE%TYPE := ’90’;
G_DG_MANIFEST_DELETED TMS_DG_MANIFEST.STATUS_CODE%TYPE := ’80’;
G_DG_MANIFEST_COMPLETED TMS_DG_MANIFEST.STATUS_CODE%TYPE := ’95’;

v_num_day numeric;
v_batch_count numeric;
v_log_count numeric := 0;
v_local_batch_count numeric;
BEGIN
v_batch_count := 0;
LOOP
update tms_container_loading
set status_code = G_CNTR_LOADING_EXPIRED
, last_update_tm = clock_timestamp()::timestamp(0)
, last_update_user_an = G_LAST_UPDATE_USER_SYSTEM
, last_update_module_code = G_LAST_UPDATE_MODULE_BATCH
where tms$vvd.is_vessel_departed(vessel_visit_c,trunc(clock_timestamp()::timestamp(0))) = 1
and coalesce(status_code,’

‘) <> G_CNTR_LOADING_EXPIRED and ctid in (select a.ctid from tms_container_loading where tms$vvd.is_vessel_departed(vessel_visit_c,trunc(clock_timestamp()::timestamp(0))) = 1
and coalesce(status_code,’

‘) <> G_CNTR_LOADING_EXPIRED LIMIT 20000);
EXIT WHEN NOT FOUND; /* apply on SQL */
GET DIAGNOSTICS v_local_batch_count = ROW_COUNT; v_batch_count := v_batch_count + v_local_batch_count;
COMMIT;
END LOOP;
v_log_count := v_log_count + 1; CALL Log(v_batch_count,’TMS_CONTAINER_LOADING’,NULL, ‘TMS$BATCH_JOB’, v_log_count);
COMMIT;
END;
$BODY$;

Re: ERROR : invalid transaction termination : PostgreSQL v12

What is the point of COMMITting after a few records? Why not let the whole batch run through. If there are any errors, PostgreSQL will rollback the whole transaction anyway.

As opposed to Oracle, PostgreSQL won’t commit some records, while others failed within the same transaction. As soon as a single operation within a transaction fails, it’s dead and all subsequent operations will fail.

CREATE OR REPLACE PROCEDURE TEST_TRANSACTION(
)
LANGUAGE ‘plpgsql’
SECURITY DEFINER
AS $BODY$
DECLARE
G_LAST_UPDATE_USER_SYSTEM VARCHAR2(6) := ‘SYSTEM’;
G_LAST_UPDATE_MODULE_BATCH VARCHAR2(5) := ‘BATCH’;

G_CNTR_LOADING_EXPIRED TMS_CONTAINER_LOADING.STATUS_CODE%TYPE := ’90’;
G_DG_MANIFEST_DELETED TMS_DG_MANIFEST.STATUS_CODE%TYPE := ’80’;
G_DG_MANIFEST_COMPLETED TMS_DG_MANIFEST.STATUS_CODE%TYPE := ’95’;

v_num_day numeric;
v_batch_count numeric;
v_log_count numeric := 0;
v_local_batch_count numeric;
BEGIN
v_batch_count := 0;
LOOP
update tms_container_loading
set status_code = G_CNTR_LOADING_EXPIRED
, last_update_tm = clock_timestamp()::timestamp(0)
, last_update_user_an = G_LAST_UPDATE_USER_SYSTEM
, last_update_module_code = G_LAST_UPDATE_MODULE_BATCH
where tms$vvd.is_vessel_departed(vessel_visit_c,trunc(clock_timestamp()::timestamp(0))) = 1
and coalesce(status_code,’

‘) <> G_CNTR_LOADING_EXPIRED and ctid in (select a.ctid from tms_container_loading where tms$vvd.is_vessel_departed(vessel_visit_c,trunc(clock_timestamp()::timestamp(0))) = 1
and coalesce(status_code,’

‘) <> G_CNTR_LOADING_EXPIRED LIMIT 20000);
EXIT WHEN NOT FOUND; /* apply on SQL */
GET DIAGNOSTICS v_local_batch_count = ROW_COUNT; v_batch_count := v_batch_count + v_local_batch_count;
COMMIT;
END LOOP;
v_log_count := v_log_count + 1; CALL Log(v_batch_count,’TMS_CONTAINER_LOADING’,NULL, ‘TMS$BATCH_JOB’, v_log_count);
COMMIT;
END;
$BODY$;

Источник

Недействительное завершение транзакции

У меня есть процедура, которая, когда я выполняю в dbeaver, отлично работает без проблем, однако, когда я вызываю ее из внешней программы, я получаю сообщение об ошибке ниже. Я не хочу копировать / вставлять здесь полную процедуру, потому что она довольно большая и работает в инструменте db. Я просто копирую / вставляю верх и низ. Что могло быть причиной этого?

Процедура:

Ошибка:

1 ответ

Управление транзакциями возможно только в вызовах CALL или DO с верхнего уровня или вложенных вызовах CALL или DO без какой-либо другой промежуточной команды. Например, если стек вызовов CALL proc1() → CALL proc2() → CALL proc3() , то вторая и третья процедуры могут выполнять действия по управлению транзакциями. Но если стек вызовов CALL proc1() → SELECT func2() → CALL proc3() , то последняя процедура не может управлять транзакцией из-за SELECT между ними.

Есть и другие, недокументированные ограничения:

Вы не можете явно начать транзакцию с помощью BEGIN и зафиксировать ее внутри транзакции. Таким образом, следующее не удастся:

Это может быть улучшено в будущих выпусках.

Все процедуры в стеке вызовов должны быть написаны на PL / pgSQL:

Как бы то ни было, контроль транзакций внутри процедур PostgreSQL несколько ограничен.

Если вы нарушите какое-либо из этих правил, вы получите сообщение об ошибке, описанное в вашем вопросе. Вероятно, вам придется обрабатывать транзакции в приложении, а не в процедуре — возможно, разделение процедуры на более мелкие части делает это возможным.

Источник

Thread: ERROR : invalid transaction termination : PostgreSQL v12

ERROR : invalid transaction termination : PostgreSQL v12

CREATE OR REPLACE PROCEDURE TEST_TRANSACTION(
)
LANGUAGE ‘plpgsql’
В В SECURITY DEFINER
AS $BODY$
DECLARE
В В G_LAST_UPDATE_USER_SYSTEM VARCHAR2(6) := ‘SYSTEM’;
В В G_LAST_UPDATE_MODULE_BATCH VARCHAR2(5) := ‘BATCH’;

В В G_CNTR_LOADING_EXPIRED TMS_CONTAINER_LOADING.STATUS_CODE%TYPE := ’90’;
В В G_DG_MANIFEST_DELETED TMS_DG_MANIFEST.STATUS_CODE%TYPE := ’80’;
В В G_DG_MANIFEST_COMPLETED TMS_DG_MANIFEST.STATUS_CODE%TYPE := ’95’;

В В v_num_day numeric;
В В v_batch_count numeric;
В В v_log_count numeric := 0;
В В v_local_batch_count numeric;
BEGIN
В В В В v_batch_count := 0;
В В В В LOOP
В В В В В В update tms_container_loading
В В В В В В В В set status_code = G_CNTR_LOADING_EXPIRED
В В В В В В В В В , last_update_tm = clock_timestamp()::timestamp(0)
В В В В В В В В В , last_update_user_an = G_LAST_UPDATE_USER_SYSTEM
В В В В В В В В В , last_update_module_code = G_LAST_UPDATE_MODULE_BATCH
В В В В В В В whereВ tms$vvd.is_vessel_departed(vessel_visit_c,trunc(clock_timestamp()::timestamp(0)))В = 1
В В В В В В В В and coalesce(status_code,’

‘) <> G_CNTR_LOADING_EXPIRED В and ctid in (select a.ctid from tms_container_loading В whereВ tms$vvd.is_vessel_departed(vessel_visit_c,trunc(clock_timestamp()::timestamp(0)))В = 1
В В В В В В В В and coalesce(status_code,’

‘) <> G_CNTR_LOADING_EXPIRED LIMIT 20000);
В В В В В В EXIT WHEN NOT FOUND; /* apply on SQL */
В В В В В В GET DIAGNOSTICS v_local_batch_count = ROW_COUNT; v_batch_count := v_batch_count + v_local_batch_count;
В В В В В В COMMIT;
В В В В END LOOP;
В В В В v_log_count := v_log_count + 1; CALL Log(v_batch_count,’TMS_CONTAINER_LOADING’,NULL, ‘TMS$BATCH_JOB’, v_log_count);
В В В В COMMIT;
END;
$BODY$;

Re: ERROR : invalid transaction termination : PostgreSQL v12

What is the point of COMMITting after a few records? Why not let the whole batch run through. If there are any errors, PostgreSQL will rollback the whole transaction anyway.

As opposed to Oracle, PostgreSQL won’t commit some records, while others failed within the same transaction. As soon as a single operation within a transaction fails, it’s dead and all subsequent operations will fail.

CREATE OR REPLACE PROCEDURE TEST_TRANSACTION(
)
LANGUAGE ‘plpgsql’
В В SECURITY DEFINER
AS $BODY$
DECLARE
В В G_LAST_UPDATE_USER_SYSTEM VARCHAR2(6) := ‘SYSTEM’;
В В G_LAST_UPDATE_MODULE_BATCH VARCHAR2(5) := ‘BATCH’;

В В G_CNTR_LOADING_EXPIRED TMS_CONTAINER_LOADING.STATUS_CODE%TYPE := ’90’;
В В G_DG_MANIFEST_DELETED TMS_DG_MANIFEST.STATUS_CODE%TYPE := ’80’;
В В G_DG_MANIFEST_COMPLETED TMS_DG_MANIFEST.STATUS_CODE%TYPE := ’95’;

В В v_num_day numeric;
В В v_batch_count numeric;
В В v_log_count numeric := 0;
В В v_local_batch_count numeric;
BEGIN
В В В В v_batch_count := 0;
В В В В LOOP
В В В В В В update tms_container_loading
В В В В В В В В set status_code = G_CNTR_LOADING_EXPIRED
В В В В В В В В В , last_update_tm = clock_timestamp()::timestamp(0)
В В В В В В В В В , last_update_user_an = G_LAST_UPDATE_USER_SYSTEM
В В В В В В В В В , last_update_module_code = G_LAST_UPDATE_MODULE_BATCH
В В В В В В В whereВ tms$vvd.is_vessel_departed(vessel_visit_c,trunc(clock_timestamp()::timestamp(0)))В = 1
В В В В В В В В and coalesce(status_code,’

‘) <> G_CNTR_LOADING_EXPIRED В and ctid in (select a.ctid from tms_container_loading В whereВ tms$vvd.is_vessel_departed(vessel_visit_c,trunc(clock_timestamp()::timestamp(0)))В = 1
В В В В В В В В and coalesce(status_code,’

‘) <> G_CNTR_LOADING_EXPIRED LIMIT 20000);
В В В В В В EXIT WHEN NOT FOUND; /* apply on SQL */
В В В В В В GET DIAGNOSTICS v_local_batch_count = ROW_COUNT; v_batch_count := v_batch_count + v_local_batch_count;
В В В В В В COMMIT;
В В В В END LOOP;
В В В В v_log_count := v_log_count + 1; CALL Log(v_batch_count,’TMS_CONTAINER_LOADING’,NULL, ‘TMS$BATCH_JOB’, v_log_count);
В В В В COMMIT;
END;
$BODY$;

Источник

Please explain the inscrutable rules for when «commit» in a stored proc succeeds or causes a run-time error #1957

People have blogged about the fact that commit is legal in a PostgreSQL stored proc, starting with version 11—which is what yugabyteDB Version 1.3.0 uses. Here’s an example:

However, these blogs forget that psql (and therefore ysqlsh ) have AUTOCOMMIT set to True by default. They seem to do their tests in that mode and forget that the AUTOCOMMIT mode might be False . However, things change when the AUTOCOMMIT mode is False . See the following testcase.

I would like to hear the explanation for this weird behavior. It’s add odds with the definition of autocommitting: if the insert has autocommitted, then by definition there’s nothing to commit or rollback .

Following on from this, I see no reason why call my_proc() has to start a txn. It might do no more than a calculation. As I see it, it’s the first SQL statement that’s executed from the stored proc that should start a txn. Notice that within the present regime, and given that the weakest isolation level in yugabyte DB is repeatable read , you cannot implement a stored proc to watch a table in an infinite loop and to respond when it suffers an interesting change. Unless, that is, the non-intuitive workaround that I show below helps there.

Note: this remains to be tested.

Here, for completeness, is another manifestation of the same issue. This quietly succeeds:

But this fails with «ERROR: invalid transaction termination» :

The text was updated successfully, but these errors were encountered:

Источник

Недействительное завершение транзакции

У меня есть процедура, которая, когда я выполняю в dbeaver, отлично работает без проблем, однако, когда я вызываю ее из внешней программы, я получаю сообщение об ошибке ниже. Я не хочу копировать / вставлять здесь полную процедуру, потому что она довольно большая и работает в инструменте db. Я просто копирую / вставляю верх и низ. Что могло быть причиной этого?

Процедура:

Ошибка:

1 ответ

Управление транзакциями возможно только в вызовах CALL или DO с верхнего уровня или вложенных вызовах CALL или DO без какой-либо другой промежуточной команды. Например, если стек вызовов CALL proc1() → CALL proc2() → CALL proc3() , то вторая и третья процедуры могут выполнять действия по управлению транзакциями. Но если стек вызовов CALL proc1() → SELECT func2() → CALL proc3() , то последняя процедура не может управлять транзакцией из-за SELECT между ними.

Есть и другие, недокументированные ограничения:

Вы не можете явно начать транзакцию с помощью BEGIN и зафиксировать ее внутри транзакции. Таким образом, следующее не удастся:

Это может быть улучшено в будущих выпусках.

Все процедуры в стеке вызовов должны быть написаны на PL / pgSQL:

Как бы то ни было, контроль транзакций внутри процедур PostgreSQL несколько ограничен.

Если вы нарушите какое-либо из этих правил, вы получите сообщение об ошибке, описанное в вашем вопросе. Вероятно, вам придется обрабатывать транзакции в приложении, а не в процедуре — возможно, разделение процедуры на более мелкие части делает это возможным.

Источник

Понравилась статья? Поделить с друзьями:
  • Error while checking the serial number криптопро
  • Error while evaluating uicontrol callback матлаб
  • Error while calling mysql bin mysqld exe
  • Error while evaluating expression перевод
  • Error while burning bootloader