Сообщаем, что транзакция имеет незафиксированные обновления - PullRequest
5 голосов
/ 22 декабря 2009

В нашем приложении есть обновление базы данных, которое фиксируется только после того, как выполняется последующее обновление (конечно, обе используют одну и ту же транзакцию). Однако мы обнаружили редкий поток, в котором пользователь закрывает приложение перед вторым обновлением, в результате чего первое удаляется. Я ищу способ распознать это незафиксированное обновление при выходе.

Я знаю такие проблемы, как этот призыв к редизайну, но это невозможно. Из-за редкости потока и структуры приложения мне интересно, есть ли способ просто проверить саму транзакцию на наличие незафиксированных обновлений.

Вопрос действителен для Oracle и SQLServer. Приложение написано на PowerBuilder, но его можно расширить различными способами (.NET, Win32 и т. Д.), Если это имеет значение.

Ответы [ 7 ]

5 голосов
/ 22 декабря 2009

В Oracle вы можете вызвать DBMS_TRANSACTION.local_transaction_id. Это либо возвратит уникальный идентификатор текущей транзакции, либо NULL, если транзакция не активна.

Делись и наслаждайся.

4 голосов
/ 22 декабря 2009

Это может быть полезно

@@ TRANCOUNT (Transact-SQL)

Возвращает количество активных транзакции на текущий подключение.

2 голосов
/ 29 декабря 2009

Если вы используете PB11.5 и используете пользовательский объект транзакции, довольно легко сделать что-то, что не зависит от СУБД. В событии SQLPreview объекта транзакции просто включите логическое значение, когда проходит INSERT, UPDATE или DELETE, а затем отключите его, когда пройдут COMMIT или ROLLBACK.

На самом деле, не так уж и сложно поменять пользовательский объект транзакции, если вы используете SQLCA: приложение, свойства, дополнительные свойства, типы переменных, SQLCA. Если вы используете много отдельных соединений с базой данных с большим количеством операторов «CREATE транзакция» (стандартный поиск PB может найти это, или PBL Peeper может помочь вам найти это с переменным количеством пробелов между словами ), тогда реализовать это будет сложнее, но не невозможно.

И, ради полноты, для создания пользовательского объекта транзакции: Файл / Новый / Объект PB / Стандартный класс / Транзакция. У вас есть обычный пользовательский объект, в котором вы можете определить переменные экземпляра (например, булево значение, которое я предложил), события сценария (например, предложенное мной событие SQLPreview) и функции (вы можете создать интерфейс для этой функции, чтобы скрыть детали на случай, если вы захотите расширить их в будущем). Обратите внимание, что SQLPreview недоступен для объекта Transaction до 11.5. (Для тех, кто считает это знакомым до 11.5, DataWindow реализует SQLPreview.)

Удачи,

Терри.

1 голос
/ 22 декабря 2009

В Oracle есть представление V$TRANSACTION, которое содержит строку для каждой незафиксированной транзакции. Не существует механизма, позволяющего увидеть природу этой транзакции извне (если у вас нет встроенного инструментария в вашем коде, например, с помощью DBMS_APPLICATION_INFO.SET_MODULE()). Тем не менее, текущий сеанс может видеть, имеет ли он незафиксированную работу следующим образом:

SQL> select t.status
  2  from   v$transaction t
  3         join v$session s
  4         on s.saddr = t.ses_addr
  5  where s.sid = sys_context('userenv', 'sid')
  6  /

STATUS
----------------
ACTIVE

SQL>

Если нет незавершенных транзакций, этот запрос вернет NO_DATA_FOUND. Представления V $ по умолчанию не предоставляются пользователям, так как они действительно являются принципами DBA. Однако пользователь с соответствующей привилегией может превратить этот запрос в представление и предоставить доступ к обычным joes.

Интересно, а что бы вы хотели сделать? Предполагая, что единица работы корректно определена в двух обновлениях, наверняка было бы неправильно совершать только одно. Если вам нужно знать только то, что произошло это ненормальное завершение, вам нужна какая-то форма трассировки или регистрации.

редактировать

Боб Джарвис предлагает , используя DBMS_TRANSACTION.LOCAL_TRANSACTION_ID(). Это лучшее предложение, чем ручная работа. Представление V $ TRANSACTION также можно использовать для мониторинга незавершенных транзакций из других сеансов.

0 голосов
/ 10 марта 2010

В SQL Server 2005/2008 вы можете использовать DMV. Проверьте эту статью

0 голосов
/ 22 декабря 2009

В SQL Server запустите это:

IF @@TRANCOUNT>0 BEGIN
  ROLLBACK;
END;
0 голосов
/ 22 декабря 2009

Чтобы упростить поиск и устранение неисправностей в вашем сценарии, вы можете рассмотреть возможность использования явно именованных локальных транзакций, а также использование опции «С МАРКОЙ». Это позволяет вам записать имя явной транзакции в журнал транзакций, который вы, конечно, можете проверить на более позднем этапе, чтобы определить последовательность произошедших событий.

См. Электронную документацию по SQL Server: Отмеченные транзакции

...