powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
23 сообщений из 23, страница 1 из 1
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
    #38431216
Фотография t00kuk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день! В приложении, с которым я работаю, существует проблема - со временем ростет количество открытых курсоров, что приводит к ORA-01000.

Похоже, что проблема в этом методе:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
	
public ResultSet sqlExec(String vSql) {
		Connection conn = null;
		Statement stmt = null;
		JDBCConnectionPool connPool = getPoolConnect(); //получаем пул соединений
		try {
			conn = connPool.reserveConnection();
			stmt = conn.createStatement();
			ResultSet rs = stmt.executeQuery(vSql);
			if (conn != null) {
				connPool.releaseConnection(conn);
			}
			return rs;
		} catch (Exception e) {
			System.out.println("Ошибка выполнения запроса*: "+ vSql + " " + e.getMessage());
			return null;
		} finally {
			try {
				connPool.releaseConnection(conn);
			} catch (Exception e) {
				System.out.println("Попытка закрыть соединение не удалась.");
			}
		}
	}



ResultSet'ы, полученные данным методом, везде закрыты, однако складывается ощущение, что вызов close() не закрывает курсор. Подскажите, всё ли нормально с приведенным кодом, можно ли его использовать?

Меня смущает вот что - после того, как отрабатывает releaseConnection(), теоретически, должны закрываться все ResutSet и Statement, получаенные из него. Но почему тогда полученные из метода ResultSet'ы вообще работают за пределами этого кода, ведь соединение "отпускается" в блоке finally, а значит сеты должны быть в нем закрыты. Это наталкивает меня на мысль, что я чего-то не понимаю, поэтому прошу помощи.
...
Рейтинг: 0 / 0
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
    #38431243
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Судя по коду, функции закрытия должна выполнить другая логика которая вызывает
sqlExec извне. Вот ее и надо смотреть.
...
Рейтинг: 0 / 0
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
    #38431279
Фотография t00kuk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton, именно так, ResultSet закрывается во внешних блоках.
Это нормальная практика так делать?
Нужно ли в приведенном коде вызывать connPool.releaseConnection(conn); ?
Допустимо ли не закрывать Statement stmt в приведенном коде?
...
Рейтинг: 0 / 0
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
    #38431290
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
t00kukmayton, именно так, ResultSet закрывается во внешних блоках.
Это нормальная практика так делать?
Нет.

[quot t00kuk]Нужно ли в приведенном коде вызывать connPool.releaseConnection(conn); ?
Он уже вызывает в блоке finally.

t00kukДопустимо ли не закрывать Statement stmt в приведенном коде?
Нет.
...
Рейтинг: 0 / 0
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
    #38431293
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
t00kukmayton, именно так, ResultSet закрывается во внешних блоках.
Это нормальная практика так делать?
Нужно ли в приведенном коде вызывать connPool.releaseConnection(conn); ?
Допустимо ли не закрывать Statement stmt в приведенном коде?
Затрудняюсь сказать по поводу нормальности. Это экономно
конечно с точки зрения создания коллекций. Но надо не забывать
обязательно закрыть rs в вызываемом коде даже в случае раскрутки
Exception.

По данной проблеме. Думаю что там флудит 1 единственный метода
и 1 запрос. Его может вам указать dba если посмотрит в v$session, v$sql,
v$sqltext e.t.c. в момент ORA-01000.

По поводу JDBCConnectionPool - увы не знаю. Я не использовал его
в явном виде.
...
Рейтинг: 0 / 0
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
    #38431299
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
t00kukпосле того, как отрабатывает releaseConnection(), теоретически, должны закрываться все ResutSet и Statement, получаенные из него.
Ваши теоретические предположения ничем не подкреплены. В теории пул мог бы это делать при особом желании.
На практике ваш пул этого не делает. Как и большинство других.
В общем случае нужно закрывать Statement и ResultSet самостоятельно, всегда и в блоке finally. Это даст некоторые гарантии. И ваш код перестанет зависеть от реализии пула, драйвера и происхождения экземпляра Connection.

t00kukНо почему тогда полученные из метода ResultSet'ы вообще работают за пределами этого кода, ведь соединение "отпускается" в блоке finally, а значит сеты должны быть в нем закрыты. Это наталкивает меня на мысль, что я чего-то не понимаю, поэтому прошу помощи.
Потому что releaseConnection не закрывает соединения. А просто говорит пулу, что это соединение больше не нужно, можно отдать его кому-то другом.
...
Рейтинг: 0 / 0
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
    #38431322
Фотография t00kuk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо за ответы.
В коде приложения с ResultSet'ами, полученными из сабжа, частенько применяется следующая конструкция:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
ResultSet rs = sqlExec("select something from table");
if (rs != null){
   try{

//  ... какие-то действия ...

   }catch(Exception e){}    
    finally{rs.close()}
}



Не страшно ли то, что close() вызывается в if ?
Нужно ли вызывать close(), если rs == null ? Звучит бредово, но может в этом дело?
...
Рейтинг: 0 / 0
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
    #38431334
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
t00kukВ коде приложения с ResultSet'ами, полученными из сабжа, частенько применяется следующая конструкция:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
ResultSet rs = sqlExec("select something from table");
if (rs != null){
   try{

//  ... какие-то действия ...

   }catch(Exception e){}    
    finally{rs.close()}
}



Такой код чудесно рефакториться в JDBCTemplate. И проблема с закрытием ресурсов уходит.
...
Рейтинг: 0 / 0
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
    #38432789
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
t00kukmayton, именно так, ResultSet закрывается во внешних блоках.
Это нормальная практика так делать?
в общем случае ненормально, но:
- исключения всегда есть, только нужно оговорить это в доках другому программисту
- передавай в процедуру тогда сам conn - и эта процедура потеряет смысл.
- если не закрывать, то блок finally вообще теряет смысл. Он снаружи.
- пул для того и создан, чтобы быстро открыть, выполнить и закрыть. run(conn, sql) Тогда зачем rs тянуть во внешний блок?
Для уменьшения кода надо смотреть логику сразу во всех блоках - и внешних и внутренних.
...
Рейтинг: 0 / 0
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
    #38433057
Сергей Арсеньев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
t00kukResultSet'ы, полученные данным методом, везде закрыты, однако складывается ощущение, что вызов close() не закрывает курсор.
В некоторых версиях Oracle есть бага связанная с тем, что в ряде случаев недовычитанные курсоры остаются открытыми.
У Вас они SQL или PL/SQL?
...
Рейтинг: 0 / 0
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
    #38433862
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
t00kukResultSet'ы, полученные данным методом, везде закрыты, однако складывается ощущение, что вызов close() не закрывает курсор.
у меня складывается ощущение, что вызова close() для Statement'а нет в принципе. И ResultSet здесь вообще не при чем.

Но об этом уже было написано парой сообщений выше )))

Насколько я помню, проблема была при передаче курсоров ОТКРЫТЫХ в PL/SQL и попыткой закрытия их в Java, через Java вызовы. В общем, даже багой назвать сложно. Как я понимаю, у ТС никакие курсоры не используются, просто память не чиститься (как минимум statement не закрывает).
...
Рейтинг: 0 / 0
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
    #38433946
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С точки зрения Oracle у курсора есть состояния PARSE, EXECUTE, FETCH, CLOSED если мне не изменяет
память. Виртуальные вызовы ResultSet.close(), Statement.close() очевидно следуют стандарту JDBC
но вовсе не обязаны отображаться на состояния SQL-машины oracle один-в-один.

Для нашего случая достаточно провести 1 эксперимент с трассировкой Oracle-сессии
чтобы понять что-же всё таки закрывает курсор по настоящему (для чистоты еще провести
два теста с выфетчиванием до конца выборки и не до конца). Или просто подизассемблировать
код пакетов oracle.jdbc.*. К сож. у меня щас нет возможности. Пишу с нерабочего ноута.

Вообще тема - боян и где-то в форумах Оракла проскакивала.
...
Рейтинг: 0 / 0
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
    #38433974
Мужик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Интересно, как это вообще работает, если Connection'ы с открытыми в них курсорами могут тут же отдаться другому клиенту. А потом они вместе будут читать через один Connection несколько курсоров? Это разве поддерживается JDBC?
...
Рейтинг: 0 / 0
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
    #38433976
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МужикConnection'ы с открытыми в них курсорами могут тут же отдаться другому клиенту.
Хм.. вряд-ли. Пул не должен их никому передавать. Иначе будет хаос и нарушение ACID.
...
Рейтинг: 0 / 0
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
    #38434159
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мужик,
Он просто выше процедурой все закрывает вместе с коннектом.
...
Рейтинг: 0 / 0
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
    #38434167
Мужик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123,
так у него Connection возвращается в пул еще до возврата ResultSet. Уже с этого момента пул может выдать его кому-нибудь другому. Поэтому и удивительно, как это вообще работает.
...
Рейтинг: 0 / 0
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
    #38434379
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мужик,
Ты прав. Не заметил. Но нужно смотреть реализацию пула. Если коннект Не закрывается, то ничего страшного. Все х одят под одним пользователем.
...
Рейтинг: 0 / 0
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
    #38434467
Мужик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123Мужик,
Ты прав. Не заметил. Но нужно смотреть реализацию пула. Если коннект Не закрывается, то ничего страшного. Все х одят под одним пользователем.
Я просто ни разу не встречал JDBC-драйверов, которые позволяли бы читать в одном Connection несколько курсоров одновременно. Может, конечно, пул какой-то хитрый и не выдает другим Connection, пока не закроется все, что с ним связано (ResultSet).
...
Рейтинг: 0 / 0
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
    #38434546
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мужик,
Я бы не путал коннект и пул.
Без пула 2 объекта rs на коннект нет проблем.
...
Рейтинг: 0 / 0
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
    #38434620
just_vladimir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МужикЯ просто ни разу не встречал JDBC-драйверов, которые позволяли бы читать в одном Connection несколько курсоров одновременно. Может, конечно, пул какой-то хитрый и не выдает другим Connection, пока не закроется все, что с ним связано (ResultSet).
Хмм... я почему то всегда считал, что один Statement -> один ResultSet, а вот в рамках одного Conenction вроде как можно много Statement'ов держать. Или я ошибаюсь?
...
Рейтинг: 0 / 0
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
    #38434669
Мужик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
just_vladimirХмм... я почему то всегда считал, что один Statement -> один ResultSet, а вот в рамках одного Conenction вроде как можно много Statement'ов держать. Или я ошибаюсь?
Я не работал с Oracle. Но в тех базах, с какими мне приходилось сталкиваться, нельзя было одновременно работать в рамках одного Connection с несколькими ResultSet.
...
Рейтинг: 0 / 0
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
    #38434929
just_vladimir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мужик,
если верить спеке jdbc, то на один Connection допускается множество Statement'ом, а вот уже на каждый Statement будет по одному ResultSet, есть и соответствующий вопросец на stackoverflow http://stackoverflow.com/questions/5149135/jdbc-statement-preparedstatement-per-connection. Другое дело, что бывают ущербные реализации, такие как jdbc-odbc bridge и в них на один Connection можно держать только один Statement, по данной теме тоже есть обсуждение на stackoverflow http://stackoverflow.com/questions/12671417/what-is-the-only-one-open-statement-per-connection-limitation-in-jdbc-odbc-bridg
...
Рейтинг: 0 / 0
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
    #38488835
Фотография t00kuk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Проблема с курсорами решилась заменой реализации пула на BoneCP.

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

Всем спасибо!
...
Рейтинг: 0 / 0
23 сообщений из 23, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]