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

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

Даже самый дурацкий замысел можно воплотить мастерски
Запускаю клиентов так: открываю два Far'a, запускаю "java -jar <имя>.jar param1 param2" в каждом Far'e, параметры свои для каждого клиента. Таким образом клиенты запущенны в разных процессах. У каждого есть своя коннекция.
Innate, как ты их запускаешь не суть важно.
Вообще говоря, я припоминаю подобное сообщение об ошибке, только я такого эффекта добивался в одном приложении.
Причём один и тот же код работал с Sybase, но не желал работать с MS SQL. Если мне мой склероз не изменяет, то один из способов решения проблемы заключался в смене драйвера...
Но всё же, ты возможно используешь оду и ту же коннекцию сам не догадываясь об этом. Дело в том, что создание коннекций занятие довольно дорогостоящее (по времени). Поэтому ODBC драйвер может не закрывать коннекцию, а ждать некоторое время, не понадобиться ли она кому-нибудь ещё. См. закладку Connection Pooling у ODBC Data Source Administrator.
Чтобы подтвердить или опровергнуть мои предположения, просто запусти свои программы (точнее их процесс обращения с БД) не одновременно, а с интервалом более 2-х минут (дефолтное время ожидания переиспользования коннекции).
Вообще говоря, я припоминаю подобное сообщение об ошибке, только я такого эффекта добивался в одном приложении.
Причём один и тот же код работал с Sybase, но не желал работать с MS SQL. Если мне мой склероз не изменяет, то один из способов решения проблемы заключался в смене драйвера...
Но всё же, ты возможно используешь оду и ту же коннекцию сам не догадываясь об этом. Дело в том, что создание коннекций занятие довольно дорогостоящее (по времени). Поэтому ODBC драйвер может не закрывать коннекцию, а ждать некоторое время, не понадобиться ли она кому-нибудь ещё. См. закладку Connection Pooling у ODBC Data Source Administrator.
Чтобы подтвердить или опровергнуть мои предположения, просто запусти свои программы (точнее их процесс обращения с БД) не одновременно, а с интервалом более 2-х минут (дефолтное время ожидания переиспользования коннекции).
Даже самый дурацкий замысел можно воплотить мастерски
Коннекция открывается в начале и не закрывается до конца. Дело в том, что программа постоянно пишет и читает из базы данных, и я посчитал, что постоянно открывать и закрывать коннекцию будет долго. Таким образом, как я понимаю, когда запускается второй клиент, у первого уже есть коннекция, поэтому у них разные коннекции.
Не знаю, что там может происходить.

"Лучше полдня потерять потом за 5 минут долететь"
Может стоит обратить внимание на EJB и JBoss ??
сервер сам разгребет за тебя всю муть по обращению к базе данных
а EJB - по большому счету всего лишь форма записи класса
Может стоит обратить внимание на EJB и JBoss ??
сервер сам разгребет за тебя всю муть по обращению к базе данных
а EJB - по большому счету всего лишь форма записи класса
Спасибо всем за помощь, я нашел ошибку. :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...
}
}
Еще раз всем большое спасибо!
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...
}
}