Русский English Тэги View Sergey Zolotaryov's profile on LinkedIn Вход
100 причин любить MSSQL (причина 1-я)
Постоянная ссылка 28-09-2016 anydoby java mssql

Уже несколько месяцев плотно занимаюсь переходом одного жирного клиента с Oracle на MS SQL (по причине значительной дешевизны последнего относительно первого). Как обычно, клиент за маленькие деньги хочет сделать из овцы семь шапок.

После многочисленных находок в сфере отличия производительности (update и особенно merge) мы вплотную приблизились к продакшену.

И тут начались проблемы. Видели вы вот такое?


org.springframework.transaction.CannotCreateTransactionException: 
Could not open JDBC Connection for transaction; nested exception is com.microsoft.sqlserver.jdbc.SQLServerException: 
The TCP/IP connection to the host *******, port 1433 has failed. 
Error: "Cannot assign requested address. Verify the connection properties. 
Make sure that an instance of SQL Server is running on the host and accepting TCP/IP connections at the port. 
Make sure that TCP connections to the port are not blocked by a firewall.

И это при том, что на стороне базы всё чисто, свободных соединений много. Используется родной com.microsoft.sqlserver.jdbc.SQLServerConnectionPoolDataSource. Кол-во соединений контролируется в приложении, т.е. явно что-то не так с OS.

Оказалось, что при частом открытии-закрытии соединений, OS некоторое время держит временные порты, которые были открыты для соединения с базой. Если закрывать-открывать часто (а у нас 250 потоков это делают ежесекундно), то порты заканчиваются и видим ошибку выше. Пул от микрософта, на самом деле, не пул и соединения закрывает, когда мы говорим Connection.close(). Зачем было называть его PoolDataSource непонятно. Кстати, ещё одна его подозрительная особенность - у него нет максимума соединений, нет таймаутов, нет многих настроек, характерных для нормальных пулов (от Oracle или Apache).

Мораль: не использовать com.microsoft.sqlserver.jdbc.SQLServerConnectionPoolDataSource в продакшен, а использовать, например, org.apache.commons.dbcp.BasicDataSource в связке с com.microsoft.sqlserver.jdbc.SQLServerDriver, который с недавних пор работает на Linux.

Добавить комментарий

Предыдущая статья ConcurrentModificationException в java.util.ServiceLoader