powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Зависает!
14 сообщений из 14, страница 1 из 1
Зависает!
    #38417939
GorloPavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте. Столкнулся с непонятной проблемой. Иногда программа зависает на создании подключения(DriverManager.getConnection). Эта функция не единственная. Дело в том что ее могут вызывать сразу несколько потоков. И если в одном из вызовов зависло, то все... Остальные ждут пока поток вызвавший ее не разблокирует. В чем может быть причина?

Пример функции:
Код: 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.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
public synchronized void setHostBusy(Session session,int busy){
		
		Connection mConnection=null;
		CallableStatement mStatement=null;
		
		try {   
			try{
				mConnection = DriverManager.getConnection(HUB_DB_URL, HUB_USER_NAME,HUB_USER_PASSWORD);
				mConnection.setAutoCommit(false);
				
				mStatement=mConnection.prepareCall("CALL SET_HOST_BUSY(?,?)");
				mStatement.setInt(1, session.host_id);
				mStatement.setInt(2, busy);
				
				mStatement.executeQuery();
				mConnection.commit();
				
				notifyUsers(session.host_id);
			}
			catch(SQLException e){
				session.disconnect();
				mConnection.rollback();
				logError(e, "setHostBusy");
			}
		}
		catch(Exception e){
			session.disconnect();
			logError(e, "setHostBusy");
		}
		finally{	
			try{
				if(mStatement!=null){mStatement.close();}
				if(mConnection!=null){mConnection.close();}
			}
			catch(SQLException e){
				logError(e, "setHostBusy");
			}
		}
	}
...
Рейтинг: 0 / 0
Зависает!
    #38418226
Мужик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GorloPavelВ чем может быть причина?
Видимо в драйвере JDBC. Можно снять дамп потоков и посмотреть, где зависло.
...
Рейтинг: 0 / 0
Зависает!
    #38418245
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1) За DriverManager.getConnection() как правило скрывается пул соединений ограниченного размера. Когда другие потоки забрали все потоки, очередной поток зависнет на этом методе до тех пор, пока не появится доступного соединения.
2) У вас метод в добавок ко всему объявлен synchronized, что привносит дополнительную блокировку. Пока один поток ждет получения соединения, другие потоки не могут войти в этот метод.
3) У вас некорректно написан последний try-catch блок. Если у вас mStatement.close() бросит исключение, то mConnection.close() уже не будет вызван. Так писать нельзя.
...
Рейтинг: 0 / 0
Зависает!
    #38418302
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GorloPavel,

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
НАЧАЛО_ПРОГРАММЫ() { 
    mConnection = DriverManager.getConnection(HUB_DB_URL, HUB_USER_NAME,HUB_USER_PASSWORD); 
}

SYNCHRONIZED_ФУНКЦИЯ() { 
   mStatement=...
   mStatement.executeQuery();
   mConnection.commit();
   mStatement.close();
 }

КОНЕЦ_ПРОГРАММЫ() { 
    mConnection.close(); 
}
...
Рейтинг: 0 / 0
Зависает!
    #38418305
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
UsmanGorloPavel,

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
НАЧАЛО_ПРОГРАММЫ() { 
    mConnection = DriverManager.getConnection(HUB_DB_URL, HUB_USER_NAME,HUB_USER_PASSWORD); 
}

SYNCHRONIZED_ФУНКЦИЯ() { 
   mStatement=...
   mStatement.executeQuery();
   mConnection.commit();
   mStatement.close();
 }

КОНЕЦ_ПРОГРАММЫ() { 
    mConnection.close(); 
}
Это плохая практика. Как правило, так не делают. Зачем держать соединение, если оно не используется? Корректный сценарий работы с пулом соединений: установить (или получить из пула) соединение непосредственно перед тем, как оно потребуется, закрыть (или вернуть его в пул), как только оно больше не нужно.
...
Рейтинг: 0 / 0
Зависает!
    #38418306
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjv1) За DriverManager.getConnection() как правило скрывается пул соединений ограниченного размера. Когда другие потоки забрали все потоки, очередной поток зависнет на этом методе до тех пор, пока не появится доступного соединения..Что-то я затупил и вместо DriverManager увидел DataSource За DriverManager пулов обычно нет, поэтому мой п.1 нужно проигнорировать.
...
Рейтинг: 0 / 0
Зависает!
    #38418311
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GorloPavelЭта функция не единственнаяcdtyjv,

Предположим, что у ТС есть функция getHostBusy(...) , которая опрашивает базу с интервалом в 2 сек. в отдельном потоке...
...
Рейтинг: 0 / 0
Зависает!
    #38418318
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
UsmanПредположим, что у ТС есть функция getHostBusy(...) , которая опрашивает базу с интервалом в 2 сек. в отдельном потоке...А теперь давайте предположим, что на очередной итерации ваша соединение внезапно оказывается закрытым (сетка глюканула, СУБД перезагрузили, и т.д.). Что будете делать?
...
Рейтинг: 0 / 0
Зависает!
    #38418320
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjvЧто будете делать?Конечно же реконнект.
...
Рейтинг: 0 / 0
Зависает!
    #38418331
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Но тогда вот это код надо менять, ибо он не учитывает реконнект:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
НАЧАЛО_ПРОГРАММЫ() { 
   mConnection = DriverManager.getConnection(HUB_DB_URL, HUB_USER_NAME,HUB_USER_PASSWORD);
}

SYNCHRONIZED_ФУНКЦИЯ() {
   mStatement=...
   mStatement.executeQuery();
   mConnection.commit();
   mStatement.close();
}

КОНЕЦ_ПРОГРАММЫ() { 
   mConnection.close();
}
...
Рейтинг: 0 / 0
Зависает!
    #38418427
GorloPavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjvНо тогда вот это код надо менять, ибо он не учитывает реконнект:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
НАЧАЛО_ПРОГРАММЫ() { 
   mConnection = DriverManager.getConnection(HUB_DB_URL, HUB_USER_NAME,HUB_USER_PASSWORD);
}

SYNCHRONIZED_ФУНКЦИЯ() {
   mStatement=...
   mStatement.executeQuery();
   mConnection.commit();
   mStatement.close();
}

КОНЕЦ_ПРОГРАММЫ() { 
   mConnection.close();
}



А что делть если у меня несколько функций и несколько потоков которые вызывают их? Что будет если в первой функции произойдет rollback а в первой еще не выполнился запрос? mConnection же один!
...
Рейтинг: 0 / 0
Зависает!
    #38418470
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GorloPavel ,
Connection не является thread-safe, с ним нельзя работать из разных потоков.
...
Рейтинг: 0 / 0
Зависает!
    #38418476
GorloPavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjv GorloPavel ,
Connection не является thread-safe, с ним нельзя работать из разных потоков.
Ну так у меня же он создается каждый раз? Функция synchronized, значит только один поток с ним может работать. Потом Connection закрывается. А следующий поток делает тоже самое.
...
Рейтинг: 0 / 0
Зависает!
    #38418499
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GorloPavel ,
Thread dump.
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Зависает!
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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