Могу ли я получить 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