Oracle OCI не запрашивает кешированный результат

Я разрабатываю программу на C ++ с использованием OCI для запроса некоторого набора результатов из базы данных Oracle. Я обнаружил, что набор результатов кэшируется, даже если я вручную обновляю строки с помощью 'update table set col=xxx where xxx'. Для вызовов OCI по-прежнему используются старые данные. Как происходит это кеширование? Есть ли способ его отключить? Как я могу проверить, действительно ли происходит кеширование? Проверяя план выполнения?


person Stan    schedule 21.08.2012    source источник
comment
Вы обновляете строки в одном сеансе? Или в другом сеансе? Вы фиксируете обновления? Какой уровень изоляции транзакций использует ваше приложение?   -  person Justin Cave    schedule 21.08.2012
comment
1. Отличное занятие. Обновление строк в SQL Plus. Если запросить тот же набор результатов в SQL Plus, можно получить обновленные данные, но не через OCI. 2. Нужно ли делать коммит в SQL * Plus? 3. Не ставил. Так что это уровень изоляции по умолчанию.   -  person Stan    schedule 21.08.2012


Ответы (2)


Когда вы вносите изменения в отдельном сеансе (сеансе SQL * Plus), эти изменения становятся видимыми только для текущего сеанса (вашего приложения OCI), когда вы commit вносите изменения. Пока вы не commit транзакцию в SQL * Plus, вы по-прежнему будете видеть текущую версию строки, а не версию, которую вы изменили в сеансе SQL * Plus. Ваше приложение OCI использует изоляцию транзакций по умолчанию READ COMMITTED, поэтому вы можете читать только зафиксированные данные.

Следует помнить, что если вы открываете курсор из своего приложения OCI, данные, которые извлекаются из дескриптора курсора, являются данными в том виде, в каком они существовали в момент открытия курсора. Поэтому, если вы открываете курсор в OCI, фиксируете изменения в SQL * Plus, а затем извлекаете данные из OCI, ваше приложение OCI не увидит изменений, которые были зафиксированы в SQL * Plus. Вам придется повторно открыть курсор, чтобы увидеть только что зафиксированные строки.

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

person Justin Cave    schedule 21.08.2012

Да, вам нужно будет выполнить фиксацию в SQL * Plus или SET AUTOCOMMIT ON.

Если посмотреть на план запроса, вы увидите, используется ли кэш результатов клиента, вы увидите RESULT CACHE в столбце Operation.

person Gaius    schedule 21.08.2012