|
|
|
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
|
|||
|---|---|---|---|
|
#18+
Добрый день! В приложении, с которым я работаю, существует проблема - со временем ростет количество открытых курсоров, что приводит к 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. ResultSet'ы, полученные данным методом, везде закрыты, однако складывается ощущение, что вызов close() не закрывает курсор. Подскажите, всё ли нормально с приведенным кодом, можно ли его использовать? Меня смущает вот что - после того, как отрабатывает releaseConnection(), теоретически, должны закрываться все ResutSet и Statement, получаенные из него. Но почему тогда полученные из метода ResultSet'ы вообще работают за пределами этого кода, ведь соединение "отпускается" в блоке finally, а значит сеты должны быть в нем закрыты. Это наталкивает меня на мысль, что я чего-то не понимаю, поэтому прошу помощи. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.10.2013, 13:56:04 |
|
||
|
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
|
|||
|---|---|---|---|
|
#18+
Судя по коду, функции закрытия должна выполнить другая логика которая вызывает sqlExec извне. Вот ее и надо смотреть. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.10.2013, 14:09:05 |
|
||
|
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
|
|||
|---|---|---|---|
|
#18+
mayton, именно так, ResultSet закрывается во внешних блоках. Это нормальная практика так делать? Нужно ли в приведенном коде вызывать connPool.releaseConnection(conn); ? Допустимо ли не закрывать Statement stmt в приведенном коде? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.10.2013, 14:17:35 |
|
||
|
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
|
|||
|---|---|---|---|
|
#18+
t00kukmayton, именно так, ResultSet закрывается во внешних блоках. Это нормальная практика так делать? Нет. [quot t00kuk]Нужно ли в приведенном коде вызывать connPool.releaseConnection(conn); ? Он уже вызывает в блоке finally. t00kukДопустимо ли не закрывать Statement stmt в приведенном коде? Нет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.10.2013, 14:21:05 |
|
||
|
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
|
|||
|---|---|---|---|
|
#18+
t00kukmayton, именно так, ResultSet закрывается во внешних блоках. Это нормальная практика так делать? Нужно ли в приведенном коде вызывать connPool.releaseConnection(conn); ? Допустимо ли не закрывать Statement stmt в приведенном коде? Затрудняюсь сказать по поводу нормальности. Это экономно конечно с точки зрения создания коллекций. Но надо не забывать обязательно закрыть rs в вызываемом коде даже в случае раскрутки Exception. По данной проблеме. Думаю что там флудит 1 единственный метода и 1 запрос. Его может вам указать dba если посмотрит в v$session, v$sql, v$sqltext e.t.c. в момент ORA-01000. По поводу JDBCConnectionPool - увы не знаю. Я не использовал его в явном виде. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.10.2013, 14:23:50 |
|
||
|
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
|
|||
|---|---|---|---|
|
#18+
t00kukпосле того, как отрабатывает releaseConnection(), теоретически, должны закрываться все ResutSet и Statement, получаенные из него. Ваши теоретические предположения ничем не подкреплены. В теории пул мог бы это делать при особом желании. На практике ваш пул этого не делает. Как и большинство других. В общем случае нужно закрывать Statement и ResultSet самостоятельно, всегда и в блоке finally. Это даст некоторые гарантии. И ваш код перестанет зависеть от реализии пула, драйвера и происхождения экземпляра Connection. t00kukНо почему тогда полученные из метода ResultSet'ы вообще работают за пределами этого кода, ведь соединение "отпускается" в блоке finally, а значит сеты должны быть в нем закрыты. Это наталкивает меня на мысль, что я чего-то не понимаю, поэтому прошу помощи. Потому что releaseConnection не закрывает соединения. А просто говорит пулу, что это соединение больше не нужно, можно отдать его кому-то другом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.10.2013, 14:25:39 |
|
||
|
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
|
|||
|---|---|---|---|
|
#18+
Спасибо за ответы. В коде приложения с ResultSet'ами, полученными из сабжа, частенько применяется следующая конструкция: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. Не страшно ли то, что close() вызывается в if ? Нужно ли вызывать close(), если rs == null ? Звучит бредово, но может в этом дело? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.10.2013, 14:33:49 |
|
||
|
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
|
|||
|---|---|---|---|
|
#18+
t00kukВ коде приложения с ResultSet'ами, полученными из сабжа, частенько применяется следующая конструкция: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. Такой код чудесно рефакториться в JDBCTemplate. И проблема с закрытием ресурсов уходит. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.10.2013, 14:39:21 |
|
||
|
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
|
|||
|---|---|---|---|
|
#18+
t00kukmayton, именно так, ResultSet закрывается во внешних блоках. Это нормальная практика так делать? в общем случае ненормально, но: - исключения всегда есть, только нужно оговорить это в доках другому программисту - передавай в процедуру тогда сам conn - и эта процедура потеряет смысл. - если не закрывать, то блок finally вообще теряет смысл. Он снаружи. - пул для того и создан, чтобы быстро открыть, выполнить и закрыть. run(conn, sql) Тогда зачем rs тянуть во внешний блок? Для уменьшения кода надо смотреть логику сразу во всех блоках - и внешних и внутренних. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2013, 13:33:58 |
|
||
|
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
|
|||
|---|---|---|---|
|
#18+
t00kukResultSet'ы, полученные данным методом, везде закрыты, однако складывается ощущение, что вызов close() не закрывает курсор. В некоторых версиях Oracle есть бага связанная с тем, что в ряде случаев недовычитанные курсоры остаются открытыми. У Вас они SQL или PL/SQL? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2013, 15:53:09 |
|
||
|
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
|
|||
|---|---|---|---|
|
#18+
t00kukResultSet'ы, полученные данным методом, везде закрыты, однако складывается ощущение, что вызов close() не закрывает курсор. у меня складывается ощущение, что вызова close() для Statement'а нет в принципе. И ResultSet здесь вообще не при чем. Но об этом уже было написано парой сообщений выше ))) Насколько я помню, проблема была при передаче курсоров ОТКРЫТЫХ в PL/SQL и попыткой закрытия их в Java, через Java вызовы. В общем, даже багой назвать сложно. Как я понимаю, у ТС никакие курсоры не используются, просто память не чиститься (как минимум statement не закрывает). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.10.2013, 13:35:56 |
|
||
|
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
|
|||
|---|---|---|---|
|
#18+
С точки зрения Oracle у курсора есть состояния PARSE, EXECUTE, FETCH, CLOSED если мне не изменяет память. Виртуальные вызовы ResultSet.close(), Statement.close() очевидно следуют стандарту JDBC но вовсе не обязаны отображаться на состояния SQL-машины oracle один-в-один. Для нашего случая достаточно провести 1 эксперимент с трассировкой Oracle-сессии чтобы понять что-же всё таки закрывает курсор по настоящему (для чистоты еще провести два теста с выфетчиванием до конца выборки и не до конца). Или просто подизассемблировать код пакетов oracle.jdbc.*. К сож. у меня щас нет возможности. Пишу с нерабочего ноута. Вообще тема - боян и где-то в форумах Оракла проскакивала. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.10.2013, 15:26:08 |
|
||
|
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
|
|||
|---|---|---|---|
|
#18+
Интересно, как это вообще работает, если Connection'ы с открытыми в них курсорами могут тут же отдаться другому клиенту. А потом они вместе будут читать через один Connection несколько курсоров? Это разве поддерживается JDBC? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.10.2013, 16:15:49 |
|
||
|
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
|
|||
|---|---|---|---|
|
#18+
МужикConnection'ы с открытыми в них курсорами могут тут же отдаться другому клиенту. Хм.. вряд-ли. Пул не должен их никому передавать. Иначе будет хаос и нарушение ACID. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.10.2013, 16:19:47 |
|
||
|
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
|
|||
|---|---|---|---|
|
#18+
Мужик, Он просто выше процедурой все закрывает вместе с коннектом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.10.2013, 20:56:39 |
|
||
|
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
|
|||
|---|---|---|---|
|
#18+
Petro123, так у него Connection возвращается в пул еще до возврата ResultSet. Уже с этого момента пул может выдать его кому-нибудь другому. Поэтому и удивительно, как это вообще работает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.10.2013, 21:07:32 |
|
||
|
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
|
|||
|---|---|---|---|
|
#18+
Мужик, Ты прав. Не заметил. Но нужно смотреть реализацию пула. Если коннект Не закрывается, то ничего страшного. Все х одят под одним пользователем. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.10.2013, 10:05:47 |
|
||
|
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
|
|||
|---|---|---|---|
|
#18+
Petro123Мужик, Ты прав. Не заметил. Но нужно смотреть реализацию пула. Если коннект Не закрывается, то ничего страшного. Все х одят под одним пользователем. Я просто ни разу не встречал JDBC-драйверов, которые позволяли бы читать в одном Connection несколько курсоров одновременно. Может, конечно, пул какой-то хитрый и не выдает другим Connection, пока не закроется все, что с ним связано (ResultSet). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.10.2013, 13:42:24 |
|
||
|
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
|
|||
|---|---|---|---|
|
#18+
Мужик, Я бы не путал коннект и пул. Без пула 2 объекта rs на коннект нет проблем. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.10.2013, 15:29:41 |
|
||
|
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
|
|||
|---|---|---|---|
|
#18+
МужикЯ просто ни разу не встречал JDBC-драйверов, которые позволяли бы читать в одном Connection несколько курсоров одновременно. Может, конечно, пул какой-то хитрый и не выдает другим Connection, пока не закроется все, что с ним связано (ResultSet). Хмм... я почему то всегда считал, что один Statement -> один ResultSet, а вот в рамках одного Conenction вроде как можно много Statement'ов держать. Или я ошибаюсь? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.10.2013, 16:42:40 |
|
||
|
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
|
|||
|---|---|---|---|
|
#18+
just_vladimirХмм... я почему то всегда считал, что один Statement -> один ResultSet, а вот в рамках одного Conenction вроде как можно много Statement'ов держать. Или я ошибаюсь? Я не работал с Oracle. Но в тех базах, с какими мне приходилось сталкиваться, нельзя было одновременно работать в рамках одного Connection с несколькими ResultSet. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.10.2013, 18:01:58 |
|
||
|
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
|
|||
|---|---|---|---|
|
#18+
Мужик, если верить спеке 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 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.10.2013, 00:45:28 |
|
||
|
Метод, возвращающий ResultSet и кол-во открытых курсоров Oracle.
|
|||
|---|---|---|---|
|
#18+
Проблема с курсорами решилась заменой реализации пула на BoneCP. Зато появилась новая проблема - сохранить BLOB в таблицу из приложения с помощью стейтментов этого пула ну никак не выходит. Видимо, опять пул придется менять, но это уже другая песня. Всем спасибо! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.12.2013, 13:59:08 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=38434929&tid=2128070]: |
0ms |
get settings: |
8ms |
get forum list: |
21ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
182ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
85ms |
get tp. blocked users: |
2ms |
| others: | 208ms |
| total: | 527ms |

| 0 / 0 |
