Проблема с запуском двух копий программы и доступом к БД

Модератор: Absurd

Ответить
Innate
Сообщения: 7
Зарегистрирован: 13 июн 2004, 19:20
Откуда: Санкт-Петербург

Я пишу программу, которая связывается с базой данных SQL Server'а через JDBC-ODBC. Она читает и пишет туда. Пока запускалась одна копия программы все было нормально. С одной копией все тестировалось и все нормально.
Все хранимые процедуры написаны с тем расчетом, что могут запускаться несколькими клиентами в любом порядке.
Когда запускаю две копии в двух разных процессах, обе вылетают с исключением SQLException с сообщением "ResultSet is closed". Получается, что одна копия закрыла объект другой.

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

Конечная цель - запускать клиетов на разных компах.

Если кто может чего-нибудь подсказать, буду очень благодарен.

Innate
Аватара пользователя
AiK
Сообщения: 2287
Зарегистрирован: 13 фев 2004, 18:14
Откуда: СПб
Контактная информация:

Innate, всё это как-то подозрительно звучит. Особенно
запускаю две копии в двух разных процессах
Такое теоретически может произойти, если ты в рамках одной и той же коннекции пытаешься обращаться к серверу. Но такого поведения ещё суметь добиться нужно :)
Даже самый дурацкий замысел можно воплотить мастерски
Innate
Сообщения: 7
Зарегистрирован: 13 июн 2004, 19:20
Откуда: Санкт-Петербург

Запускаю клиентов так: открываю два Far'a, запускаю "java -jar <имя>.jar param1 param2" в каждом Far'e, параметры свои для каждого клиента. Таким образом клиенты запущенны в разных процессах. У каждого есть своя коннекция.
Аватара пользователя
AiK
Сообщения: 2287
Зарегистрирован: 13 фев 2004, 18:14
Откуда: СПб
Контактная информация:

Innate, как ты их запускаешь не суть важно.
Вообще говоря, я припоминаю подобное сообщение об ошибке, только я такого эффекта добивался в одном приложении.
Причём один и тот же код работал с Sybase, но не желал работать с MS SQL. Если мне мой склероз не изменяет, то один из способов решения проблемы заключался в смене драйвера...

Но всё же, ты возможно используешь оду и ту же коннекцию сам не догадываясь об этом. Дело в том, что создание коннекций занятие довольно дорогостоящее (по времени). Поэтому ODBC драйвер может не закрывать коннекцию, а ждать некоторое время, не понадобиться ли она кому-нибудь ещё. См. закладку Connection Pooling у ODBC Data Source Administrator.

Чтобы подтвердить или опровергнуть мои предположения, просто запусти свои программы (точнее их процесс обращения с БД) не одновременно, а с интервалом более 2-х минут (дефолтное время ожидания переиспользования коннекции).
Даже самый дурацкий замысел можно воплотить мастерски
Innate
Сообщения: 7
Зарегистрирован: 13 июн 2004, 19:20
Откуда: Санкт-Петербург

Коннекция открывается в начале и не закрывается до конца. Дело в том, что программа постоянно пишет и читает из базы данных, и я посчитал, что постоянно открывать и закрывать коннекцию будет долго. Таким образом, как я понимаю, когда запускается второй клиент, у первого уже есть коннекция, поэтому у них разные коннекции. :( Не знаю, что там может происходить.
Kolinus
Сообщения: 449
Зарегистрирован: 23 авг 2004, 14:02
Откуда: Минск

"Лучше полдня потерять потом за 5 минут долететь"

Может стоит обратить внимание на EJB и JBoss ??
сервер сам разгребет за тебя всю муть по обращению к базе данных
а EJB - по большому счету всего лишь форма записи класса
Innate
Сообщения: 7
Зарегистрирован: 13 июн 2004, 19:20
Откуда: Санкт-Петербург

Спасибо всем за помощь, я нашел ошибку. :lol: Как обычно, искал не там, где надо. У меня одна хранимая процедура генерировала исключение, которое я ловил и потом обрабатывал. Но так, как запрос не был выполнен, ResultSet не был открыт. То есть я пытался закрыть не открытый ResultSet. Ошибка проявилась только в уже известных обстоятельствах, что и вывело на неверный путь поиска причины.

Еще раз всем большое спасибо!

CallableStatement cstmt = null;
ResultSet rs = null;
try
{
cstmt = m_Connection.prepareCall("{call sproc( ?, ? )}");
cstmt.setInt( 1, 1 );
for( int i = 0; i < 10; ++i )
{
cstmt.setString( 2, 2 );
try
{
rs = cstmt.executeQuery();
rs.next();
rs.getInt( 1 );
}
catch( SQLException sqle )
{
if( sqle.getErrorCode() == 2627 )
<обработка>
else
throw sqle;
}
finally
{
try //этого не было
{ //этого не было
if( rs != null )
rs.close();
} //этого не было
catch( SQLException sqle ) //этого не было
{} //этого не было

//то есть был только if...
}
}
Ответить