2011-12-18 2 views
4

У меня есть код JDBC, который извлекает данные из Oracle.java jdbc и oracle - максимальные открытые курсоры превышены

В моем методе я использую подготовленное утверждение, однако я не закрываю это подготовленное заявление. Чтобы проверить это, я побежал это в цикле и достаточно уверен, что я получил исключение:

ORA-01000: maximum open cursors exceeded 

Мой вопрос находится в случае управляемой среде (код развернут на сервере Java EE приложений с использованием пулов соединений):

  • Что происходит с приложением?
  • Неужели он никогда не сможет запустить любой SQL-запрос в базу данных, если соединение не будет закрыто/переработано? (предположим, что в пуле есть только 1 соединение)

Я предполагаю, что соединения в бассейне на самом деле не закрыты - сеанс оракула будет живым.

ответ

5

Вам необходимо закрыть объекты ResultSet, которые были возвращены при выполнении запроса. И чтобы убедиться, что вы не просачиваете курсоры, вам нужно сделать это в блоке finally. Я считаю, что это относится и к управляемой среде.

+0

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

+0

@akila - утечка объектов ResultSet (т. Е. Неспособность закрыть их) приведет к сбою запросов, что может привести к остановке приложения. –

+0

спасибо - я думаю, я просто попробую это с помощью какого-нибудь сервера приложений и подтвержу – akila

1

Максимальная ошибка открытых курсоров генерируется в базе данных оракула. Это база данных, которая имеет этот предел. Приложение будет продолжать отправлять запросы, но база данных вернет ошибку.

Когда максимальные открытые курсоры превышены, приложение (т. Е. Клиент) все равно может отправлять запросы в базу данных, но база данных просто отклонит запрос до тех пор, пока открытые курсоры не будут закрыты.

Вы можете увеличить допустимые открытые курсоры, используя что-то вроде

“ALTER SYSTEM SET OPEN_CURSORS=2000 SID=’DUMMY’”; 

Но выше не фиксируя проблему. Чтобы исправить это, вам необходимо закрыть свои соединения/результаты/PreparedStatements и т. Д.

Возможный сценарий, когда сервер приложений не сможет отправлять запросы SQL, - если количество разрешенных активных подключений в пуле подключений меньше, чем количество подключений, которое позволяет база данных.

+0

Спасибо Ziggy, поэтому в управляемой среде, как только я доберусь до максимальной проблемы с курсором, означает ли это, что если я не откажусь/не запустил/не остановил сервер приложений, я не буду быть элем для выполнения моего запроса? Я понимаю, что если я не закрываю соединения, в конечном итоге все соединения в пуле будут потребляться, а приложение будет остановлено, и мы будем вынуждены перезапустить сервер приложений. – akila

+0

Да, правильно, потому что если вы откажетесь от сервера приложений, вы освободите эти ресурсы. – ziggy

+0

спасибо Ziggy Я попробую это с помощью сервера приложений и посмотрю, какое влияние это произойдет, если я не закрываю набор результатов и подготовленные заявления – akila

2

Вы ДОЛЖНЫ закрыть подготовленное заявление, иначе вы не сможете выполнять больше запросов.

Предположим, у вас есть:

 PreparedStatement ps = conn.prepareStatement("select * from my_table"); 
     ps.execute(); 
     ps.close(); 

Вы должны выполнить ps.close, чтобы избежать этого issue.And, как сказал я @Stephen, а также закрыть ResultSet.

ResultSet rs = ps.executeQuery(); 

    rs.close(); 
    ps.close(); 
+0

искали этот ответ на пару дней. То, что вы сказали, - это первый ответ, который имел какой-то смысл. Спасибо, ты помог мне отладить мою программу. – Bojan

+0

Я рад, что это было полезно для вас =) –

Смежные вопросы