Проблема с подключением Java и MySQL

#java #mysql #database #jdbc #connection

#java #mysql #База данных #jdbc #подключение

Вопрос:

Я использую Java MySQL. Я пытаюсь добавить объемные данные (около 40 миллионов записей). Мое приложение отлично работает для пары сотен тысяч записей, но после этого оно начинает выдавать мне следующее исключение:

 Exception in thread "main" com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
    at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1116)
    at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:344)
    at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2333)
    at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2370)
    at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2154)
    at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:792)
    at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47)
    at sun.reflect.GeneratedConstructorAccessor5.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
    at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:381)
    at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:305)
    at java.sql.DriverManager.getConnection(Unknown Source)
    at java.sql.DriverManager.getConnection(Unknown Source)
    at net.jboss.Database.DatabaseConnection.getConnection(DatabaseConnection.java:48)
    at net.jboss.emp.idm.adta(mde.java:96)
    at net.jboss.emp.idm.main(mde.java:69)
Caused by: java.net.SocketException: No buffer space available (maximum connections reached?): connect
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.PlainSocketImpl.doConnect(Unknown Source)
    at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
    at java.net.PlainSocketImpl.connect(Unknown Source)
    at java.net.SocksSocketImpl.connect(Unknown Source)
    at java.net.Socket.connect(Unknown Source)
    at java.net.Socket.connect(Unknown Source)
    at java.net.Socket.<init>(Unknown Source)
    at java.net.Socket.<init>(Unknown Source)
    at com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:257)
    at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:294)
    ... 16 more
  

Я погуглил эту проблему и перепробовал почти все варианты (обновление реестра Windows, изменение моего файла.cnf, изменение глобальных параметров mysql и т.д.), Но это не работает.

Комментарии:

1. пожалуйста, не могли бы вы опубликовать здесь зарегистрированный код драйверов для jdbc

2. Пожалуйста, покажите нам свой код. Я предполагаю, что вы открываете соединение для каждой записи, но забываете закрыть его (вы должны открыть его только один раз и впоследствии использовать параметризованный запрос).

Ответ №1:

Я столкнулся с аналогичной проблемой пару часов назад. С настройками по умолчанию я мог бы записать около 15 тысяч записей за одну транзакцию. Попытка написать что-либо большее, чем это, выдала мне точно такое же сообщение («Нет свободного места в буфере (достигнуто максимальное количество подключений?): connect») .

Затем я разбил транзакции на фрагменты по 1000 записей (это позволяли требования моего приложения), и я все равно получил сообщение после 15-й итерации. Мое приложение старательно создавало новый EntityManager и закрывало его для каждой итерации.

Решением было очистить кэш для этого конкретного типа объекта в промежутках между итерациями (вы также можете очистить кэш по объекту) .

EntityManagerFactory.getCache().выселИть все или evict(…)

Ответ №2:

Кажется, соединение не закрывается должным образом. Я бы порекомендовал вам использовать cобъединение в пул

Также смотрите

Комментарии:

1. Спасибо за ответ, я правильно открываю и закрываю соединения. Если это так, то почему это работает для первых нескольких сотен тысяч записей?

2. в сообщении об ошибке говорится, (maximum connections reached?) что, вероятно, после некоторых транзакций соединение не закрывается должным образом, и поэтому результат..

3. Я дважды проверил и не обнаружил никаких проблем с общим количеством подключений.

Ответ №3:

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

Ответ №4:

У меня была точно такая же проблема, и я исправил ее с помощью connectionname.close(); инструкции после каждого вызова исполняемого оператора.

Ответ №5:

теперь это может решить вашу проблему 🙂 Исключение CommunicationsException

Комментарии:

1. пожалуйста, опубликуйте ответ здесь, а не ссылайтесь на свой WordPress