Могу ли я получить ORA-08177, если есть только одно соединение с базой данных?

Мне было поручено запустить модульные тесты на штормовом бэкэнде для оракула, чтобы мы могли видеть, достаточно ли бэкэнда для использования в производстве. Одна проблема, с которой я сталкиваюсь, заключается в том, что я получаю ORA-08177 (не могу сериализовать доступ для этой транзакции), если я подключаюсь в сериализуемом режиме. Проблема исчезает, когда я использую режим фиксации чтения.

Сейчас я прочитал эту статью с вопросом о том, что это в основном проблема параллелизма.

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

Или это вероятно указывает на то, что курсор или соединение где-то не закрыто? Или транзакция не была зафиксирована или откатана?

2 ответа

Решение

"С этим связаны триггеры, но я получаю ошибки в выражениях DDL, а не при обновлении или вставке".

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

Таким образом, если вы выполняли DDL, то было бы безопасно выполнить фиксацию, изменить транзакцию на чтение зафиксированного, выполнить DDL, а затем изменить транзакцию обратно на сериализуемую. Если вы можете дать полный контрольный пример (или хотя бы тот тип DDL, о котором вы говорите), это может помочь. Например, создание материализованного представления или CREATE TABLE AS SELECT может быть "нечетным", так как это будет DDL (с его специфической фиксацией) плюс DML.

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

Рассматривать:

SQL> alter session set isolation_level=serializable;

Session altered
SQL> create table test (a number);

Table created
SQL> insert into test values (1);

1 row inserted
SQL> commit;

Commit complete
SQL> declare
  2     pragma autonomous_transaction;
  3  begin
  4     update test set a = 2;
  5     commit;
  6  end;
  7  /

PL/SQL procedure successfully completed
SQL> update test set a = 3;

update test set a = 3

ORA-08177: can't serialize access for this transaction
Другие вопросы по тегам