Oracle - Странная прерывистая ошибка с потерей данных / состояния между вызовами процедур - PullRequest
2 голосов
/ 10 февраля 2012

У меня есть ошибка, которую я пытаюсь отследить уже несколько недель, и я почти полностью изолировал, что происходит не так. Однако, почему это происходит, мне не под силу.

У меня очень большой пакет Oracle (около 4100 строк кода), и я вызываю несколько процедур. Однако данные, похоже, теряются между вызовами процедур.

Потерянные данные:

dpmethodstate varchar_state_local_type;

Сначала я называю эту процедуру:

PROCEDURE delivery_plan_set_state (
   messages OUT ReferenceCursor,
   state IN varchar_state_local_type
) AS
BEGIN
   logMessage('state COUNT is: ' || state.COUNT);
   dpmethodstate := state;
   FOR I IN 1..dpmethodstate.COUNT LOOP
      logMessage(dpmethodstate(I));
   END LOOP;
   logMessage('delivery_plan_set_state end - dpmethodstate count is now ' || dpmethodstate.COUNT);
   OPEN messages FOR SELECT * FROM TABLE(messageQueue);
   messageQueue := NULL;
END delivery_plan_set_state;

Я передаю в состояние, которое является допустимым массивом из одной строки. Я могу проверить в журналах, что dpmethodstate имеет COUNT из 1, когда процедура заканчивается.

Далее я вызываю execute_filter процедуру, которая выглядит следующим образом:

PROCEDURE execute_filter (
   --Whole bunch of OUT parameters
) AS
--About 50 different local variables being set here
BEGIN
   SELECT TO_CHAR(SYSTIMESTAMP, 'HH24:MI:SS.ff') INTO TIMING FROM DUAL;
   logMessage('[' || TIMING || '] execute_filter begin');
   logMessage('a) dpmethodstate Count is: ' || dpmethodstate.COUNT);

   --Rest of procedure

Однако на этот раз dpmethodstate.COUNT равно 0. Значение, которое я установил с delivery_plan_set_state, исчезло!

Когда я смотрю на мои журналы, это выглядит примерно так:

proposed
delivery_plan_set_state end - dpmethodstate count is now 1
[21:39:48.719017] execute_filter begin
a) dpmethodstate Count is: 0

Как видите, dpmethodstate потерялся между вызовами процедур. Есть несколько вещей, на которые стоит обратить внимание:

  1. Ничто другое в этом пакете не способно установить значение для dpmethodstate, кроме delivery_plan_set_state. И я вижу, что больше никто не назвал это.
  2. Мой код на стороне клиента написан на C #, и между двумя вызовами процедур мало что происходит.
  3. Это случается, вероятно, 1 из каждых 100 раз, поэтому очень трудно отследить или отладить.

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

1 Ответ

7 голосов
/ 10 февраля 2012

Является ли dpmethodstate глобальной переменной пакета?Я предполагаю, что это так, но я не вижу этого явно упомянутого.

Поскольку глобальные переменные пакета имеют область действия сеанса, вы уверены, что два вызова процедуры всегда используют одно и то же физическое соединение с базой данных и ничегоиспользует это соединение в промежуточный период?Если вы используете какой-то пул соединений, в котором вы получаете соединение из пула перед каждым вызовом и возвращаете соединение в пул после первого вызова, это не будет необычно в среде разработки (или среде с низким уровнем использования)чтобы получить такое же соединение 99% времени для второго вызова, но получить другой сеанс 1% времени.

Можете ли вы записать SID и SERIAL# сеанса, в котором вы устанавливаетезначение и где вы извлекаете значение?

SELECT sid, serial#
  FROM v$session
 WHERE sid = sys_context( 'USERENV', 'SID' );

Если они отличаются, вы не ожидаете, что значение сохранится.

Помимо этого, существуют другие способы очистки состояния сеансано они требуют, чтобы кто-то предпринял явные действия.Вызов DBMS_SESSION.RESET_PACKAGE или DBMS_SESSION.MODIFY_PACKAGE_STATE(DBMS_SESSION.REINITIALIZE) очистит любое состояние сеанса, установленное в вашем сеансе.Компиляция пакета будет делать то же самое, но это должно привести к ошибке, предупреждающей вас о том, что ваше состояние сеанса было отменено, когда вы пытаетесь его прочитать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...