powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / Хочется как-то поделить большую транзакцию на мелкие, а DB2 на Commit ругается.
5 сообщений из 5, страница 1 из 1
Хочется как-то поделить большую транзакцию на мелкие, а DB2 на Commit ругается.
    #38043649
Процедура обходит таблицу с XML-полем, на каждое вызывает соответствующую процедуру разбора XML и помечает строку обработанной. Вот такая:

Код: sql
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 PROCEDURE Sliv_BigLoad()
BEGIN  
	for FV1 as
		select id as fv_id
			from SEDPost.Post_XMLs
			where Loaded2='0'  AND DocType='ЕЖЕДНЕВНЫЙ_ОТЧЕТ_ПО_КБК'
	do
		call SEDPost.Sliv_Decode_KBKDaily(fv_id);
		update SEDPost.Post_XMLs
			set Loaded2='1' 
			where id=fv_id;
--		commit; 
	end for;
	
	for FV2 as
		select id as fv_id
			from SEDPost.Post_XMLs
			where Loaded='0' AND DocType ='ЕЖЕДНЕВНЫЙ_ОТЧЕТ_ПО_КБК'
	do 
		call SEDPost.Sliv_Decode_KBKProgressive(fv_id);
		update SEDPost.Post_XMLs
			set Loaded='1' 
			where id=fv_id;
--		commit; 
	end for;
-- и ещё несколько аналогичных блоков
	
END


Вот такие процедуры вызываются для разбора конкретной строки, т.е. конкретного XML:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
CREATE PROCEDURE Sliv_Decode_KBKDaily (in pID BigInt)
BEGIN
insert into SEDPost.KBKDaily (XML_ID,KODREG,pens_month, pens_year, MakeDate, Total, KBKName, KBKCode, shipdate)
select xml.id as xml_id, xml.kodreg, x.pens_month, x.pens_year, Date(x.MakeDate) as MakeDate, x.Total, varchar(x.KBKName), x.KBKCode, x.shipdate
from sedpost.post_xmls as xml,
xmltable('$c/ФайлПФР/ПачкаИсходящихДокументов/ЕЖЕДНЕВНЫЙ_ОТЧЕТ_ПО_КБК/ДоставленоНаДатуДоставки/СуммаПоКБК' passing xml.xml_content as "c"
columns pens_month smallint path '../../../ИСХОДЯЩАЯ_ОПИСЬ/Месяц',
	pens_year smallint path '../../../ИСХОДЯЩАЯ_ОПИСЬ/Год',
	makedate char(10) path '../../../ИСХОДЯЩАЯ_ОПИСЬ/ДатаФормирования',
	shipdate char(10) path '../../ДатаДоставки',
	Total decimal(12,2) path 'Сумма',
	KBKName varchar(100) path 'НаименованиеВыплатыПоКБК',
	KBKCode char(20) path 'КодВыплатыПоКБК'
) as x
where xml.id=pID;
--commit;
END


В принципе работает, но большой объём данных переполняет журнал транзакций. Журналы циклические, больше 3х гигов.
Т.е., похоже всё рассматривается как одна огромая транзакция.
Попытки вставить commit в те места, где они сейчас закомментированы, приводят к ошибке:

SQL0501N Указатель, заданный в операторах FETCH или CLOSE, не открыт, либо не
открыта переменная указателя в ссылке на скалярную функцию. SQLSTATE=24501call SEDPOST.SLIV_BigLoad
SQL0501N Указатель, заданный в операторах FETCH или CLOSE, не открыт, либо не
открыта переменная указателя в ссылке на скалярную функцию. SQLSTATE=24501

SQL0501N Указатель, заданный в операторах FETCH или CLOSE, не открыт, либо не открыта переменная указателя в ссылке на скалярную функцию.

Объяснение:

Программа пыталась выполнить одну из следующих операций:

* Оператор FETCH для выборки с помощью не открытого в этот момент
указателя.
* Оператор CLOSE для закрытия указателя, но заданный указатель не был
открыт.
* Ссылку на переменную указателя в операторе OPEN при не открытом
указателе.
* Ссылку на скалярную функцию указателя (например, на функцию
CURSOR_ROWCOUNT) при не открытом указателе.

Оператор невозможно обработать.

Действия пользователя:

Проверьте код SQL предыдущего сообщения, где, возможно, объясняется,
почему был закрыт указатель. Обратите внимание на то, что после закрытия
указателя любой оператор FETCH или CLOSE для него приводит к сообщению с
SQLCODE -501.

Если сообщений SQLCODE ранее не было получено, исправьте прикладную
программу, чтобы обеспечить открытие указателя до выполнения операторов
FETCH или CLOSE.

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

sqlcode: -501

sqlstate: 24501

DB2 9.7.

Куда бежать, дорогая редакция?
...
Рейтинг: 0 / 0
Хочется как-то поделить большую транзакцию на мелкие, а DB2 на Commit ругается.
    #38043708
CawaSPb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Честный чайник,

Код: sql
1.
2.
FOR FV1 as FV1_C CURSOR WITH HOLD FOR
   select id as fv_id ...



WITH HOLD - сохранит состояние курсора после коммита.

И update лучше:
Код: sql
1.
2.
3.
update SEDPost.Post_XMLs
   set Loaded2='1' 
   WHERE CURRENT OF FV1_C;
...
Рейтинг: 0 / 0
Хочется как-то поделить большую транзакцию на мелкие, а DB2 на Commit ругается.
    #38043721
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Честный чайник...
Куда бежать, дорогая редакция?
Если вы хотите, чтобы курсоры не закрывались при commit, то надо объявлять их так:
Код: plaintext
1.
2.
	 for  FV1 as c1 cursor with hold for
		select ...
...
Рейтинг: 0 / 0
Хочется как-то поделить большую транзакцию на мелкие, а DB2 на Commit ругается.
    #38044848
Спасибо.
Объявил курсы для for явно, перестало ругаться на commit внутри цикла.

Однако, отработать не смогло, ругается теперь так:
SQL1224N Менеджер базы данных не может принимать новые требования, прерывает
обработку всех текущих требований или указанного требования из-за ошибки или
принудительного прерывания. SQLSTATE=55032------------------------------ Введенные команды ------------------------------
call sedpost.sliv_bigload;
------------------------------------------------------------------------------
call sedpost.sliv_bigload
SQL1224N Менеджер базы данных не может принимать новые требования, прерывает
обработку всех текущих требований или указанного требования из-за ошибки или
принудительного прерывания. SQLSTATE=55032

SQL1224N Менеджер базы данных не может принимать новые требования, прерывает обработку всех текущих требований или указанного требования из-за ошибки или принудительного прерывания.

Объяснение:

Причиной этого сообщения может быть любая из следующих ситуаций.

1
* Менеджер баз данных не запущен на сервере баз данных.
* Менеджер баз данных остановлен.
* Работа агента базы данных принудительно прервана
администратором системы.
* Работа агента базы данных прервана из-за аварийного
завершения ключевого процесса менеджера баз данных.


2

Во время соединения вашего ID пользователя пользователь с
полномочиями SYSADM ввел команду FORCE QUIESCE. Поскольку у ID
пользователя нет полномочий CONNECT QUIESCE для указанной базы
данных или экземпляра и он не принадлежит к группе с
полномочиями CONNECT QUIESCE, он был отсоединен от этой базы
данных или экземпляра.


3

Программа была принудительно завершена, поскольку она
использовала больше пространства журналов, чем разрешено
параметром конфигурации базы данных max_log или num_log_span.


4

программа использует множественные контексты с локальным
протоколом. Контекст - это среда, откуда программа запускает
все операторы SQL и вызовы API. Каждое соединение, единица
работы и другие ресурсы баз данных связаны с конкретным
контекстом. Каждый контекст связан с одной или несколькими
потоками в программе. В этом случае число соединений ограничено
числом сегментов совместно используемой памяти, к которым можно
подключить отдельный процесс. Например, в операционной системе
AIX этот предел - 10 сегментов совместно используемой памяти на
один процесс.


5

В операционной системе Windows с включенной расширенной защитой
в базу данных было передано на выполнение требование от имени
ID пользователя, не входящего в группу DB2USERS или DBADMINS.
Расширенная защита предотвращает несанкционированный доступ к
продукту DB2, блокируя системные файлы DB2; по умолчанию эта
защита включена.


6

Истек срок ожидания для запроса, поскольку для
SQL_ATTR_QUERY_TIMEOUT задано слишком маленькое значение, но
срок ожидания для этого запроса не должен был истечь.
SQL_ATTR_QUERY_TIMEOUT определяет интервал в секундах для
ожидания завершения выполнения оператора SQL перед попыткой
отменить его выполнение.


7

Программа принудительно завершена после ожидания блокировки,
удерживаемой программой при помощи указателей с условием WITH
HOLD, и поставлена в очередь на выполнение в режиме
концентратора.


8

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

Дополнительные случаи для сервера объединения:

* Превышено максимальное число процессов на одного пользователя
(задаваемое maxuproc в операционной системе AIX) на уровне
операционной системы.
* В среде клиент/сервер, где используется протокол TCP/IP, номер порта,
назначенный для имени службы TCP/IP на клиенте, не совпадает с именем
порта на сервере.

Ситуация ошибки может быть обнаружена сервером объединения или
источником данных.

Действия пользователя:

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

1

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



Администратор базы данных должен посмотреть в журнале
уведомлений администратора сервера DB2 информацию о
ненормальном завершении и возможном автоматическом
восстановлении DB2 после этого ненормального завершения. Если
необходимо, обратитесь в службу программной поддержки IBM по
поводу этой проблемы.


2

Добейтесь от администратора вывода базы данных или экземпляра
из режима стабилизации или добавьте ID пользователя в группу с
полномочиями CONNECT QUIESCE. Стабилизацию можно выполнить на
уровне экземпляра, табличного пространства или базы данных.


3

Измените программу, чтобы она чаще выполняла операторы
принятия. Параметр конфигурации max_log не дает отдельным
транзакциям использовать слишком много пространства журналов.
Параметр конфигурации num_log_span не дает отдельным
транзакциям удерживать пространство журналов для повторного
использования. При разработке программы продумайте, когда
проводить принятие транзакций, чтобы предотвратить
использование пространства журналов сверх необходимого.
Возможно, стоит попросить администратора изменить параметры
журнала транзакций.


4

Либо внесите базу данных в каталог как источник данных с
обратной связью через TCP/IP, либо задайте параметр EXTSHM,
если программа его поддерживает и если ресурсов памяти хватает
для его использования.


5

При помощи инструмента Windows Управление компьютером добавьте
соответствующий ID пользователя в локальную группу защиты
Windows DB2USERS или DB2ADMNS. Обходной прием - отключить
расширенную защиту, но при этом возможны нежелательные
результаты, поскольку понизится уровень защиты в системе.


6

Измените значение SQL_ATTR_QUERY_TIMEOUT в этой прикладной
программе. Программа может использовать функцию
SQLSetStmtAttr() для задания атрибута оператора. Если программу
нельзя изменить (например, в случае программы ODBC независимого
разработчика), можно задать для QueryTimeoutInterval значение
0. Значение QueryTimeoutInterval задает для потока истечения
сроков ожидания запросов интервал между проверками истечения
сроков для запросов. Если это значение 0, драйвер CLI
игнорирует значение параметра SQL_ATTR_QUERY_TIMEOUT и, таким
образом, ожидает завершения выполнения операторов SQL перед
возвратом в программу.



Примечание: Если для QueryTimeoutInterval задано значение 0,
любая попытка программы задать значение SQL_ATTR_QUERY_TIMEOUT
приводит к SQLSTATE 01S02.


7

Увеличьте значение параметра max_coordagents в соответствии со
значением max_connections. Программы, удерживающие блокировки
для указателей WITH HOLD и помещаемые в очередь для выполнения
в режиме концентратора, могут вызывать задержки активных
агентов, ожидающих эти блокировки. Такая ситуация в сочетании с
достижением числа max_coordagents приводит к неспособности
системы обслуживать программы в очереди; в результате они не
могут освободить эти блокировки и разрешить проблему. Чтобы
уменьшить вероятность такого сценария, сконфигурируйте в
системе больше агентов координатора или сократите применение
указателей WITH HOLD.


8

Увеличьте максимально допустимое время бездействия соединения
при помощи порога CONNECTIONIDLETIME.

Если вы - пользователь системы объединения, может также потребоваться
выполнить следующие действия:

* Локализуйте проблему, определив источник данных, отклонивший
требование (процедуру по определению этого источника смотрите в
руководстве по устранению неисправностей). Убедитесь также, что
подсистема связи активна и процесс менеджера баз данных и требуемый
протокол связи запущены на сервере баз данных.
* Для операционной системы AIX проверьте значение maxuproc и при
необходимости измените его. Атрибут устройства maxuproc ограничивает
число процессов, которые можно запустить на данном сервере
объединения. По умолчанию используется значение 40.

Проверить текущее значение атрибута maxuproc можно при помощи
команды:



lsattr -E -l sys0



Чтобы узнать текущее число выполняемых на данном сервере объединения
процессов, используйте команду:



ps -ef | grep instdj1 | wc -l



где instdj1 - имя экземпляра сервера объединения.



Чтобы изменить атрибут maxuproc, используйте команду:



chdev -l sys0 -a maxuproc='nn'



где nn - новое (целое) значение maxuproc.

Если программа использует множественные контексты с локальным
протоколом, уменьшите число соединений с программой или же переключитесь
на другой протокол (например, TCP/IP). Если используется AIX Версии
4.2.1 или новее, для переменной среды EXTSHM можно задать значение ON,
чтобы увеличить число сегментов совместно используемой памяти, к которым
может быть прикреплен один процесс.

sqlcode: -1224

sqlstate: 55032

Запустил, какое-то время работало, ушёл домой.
Сервер тестовый, 9.7 под виндой. Запускал непосредственно с него из редактора команд центра управления от пользователя- администратора db2. Теоретически кто-нибудь мог базу стабилизировать (в смысле, полностью исключить этого не могу), но на админе это врядли скажется. Автоматическое обслуживание не конфигурировалось, т.е., интервал для автономного обслуживания не определён вообще, который не автономный стоит с 0 до 23. DB2 или сервер не перегружались - как был открыт по RDP центр управления на моей машине, так и стоял. О серверах объединения и речи не идёт. Журналирование циклическое 20-20-20000, должно хватать, раз commit заработал. Commit заработал(вставил в цикл перебора XML-записей), записи, которые успели загрузиться, не откатились. Загрузиться успело приблизительно 80%.

Вот...
...
Рейтинг: 0 / 0
Хочется как-то поделить большую транзакцию на мелкие, а DB2 на Commit ругается.
    #38044952
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Честный чайник,

Надо в db2diag.log смотреть...
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / Хочется как-то поделить большую транзакцию на мелкие, а DB2 на Commit ругается.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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