今天写了个模拟数据采集的程序,就是每隔20秒将执行一遍数据库插入操作,每次插入大概500行写了Servlet,tomcat启动讲执行Timer。
我写了个TimerTask,里面写了循环插入。
Dao用的是Spring JdbcTemplate。启动之后不定时的有时候1分钟,有时候2分钟,反正就是5分钟之内报错。下面是抛出的异常。Exception in thread "Timer-0" org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is com.microsoft.sqlserver.jdbc.SQLServerException: 到主机  的 TCP/IP 连接失败。 java.net.BindException: Address already in use: connect
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:82)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:577)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:641)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:670)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:678)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:710)
at org.springframework.jdbc.core.JdbcTemplate.queryForList(JdbcTemplate.java:768)
at sof.dao.DataCollector.getSpidbyDpid(DataCollector.java:82)
at sof.rt.CollectTask.run(CollectTask.java:39)
at java.util.TimerThread.mainLoop(Unknown Source)
at java.util.TimerThread.run(Unknown Source)
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: 到主机  的 TCP/IP 连接失败。 java.net.BindException: Address already in use: connect
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.loginWithoutFailover(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriverManager(DriverManagerDataSource.java:281)
at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriverManager(DriverManagerDataSource.java:269)
at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriverManager(DriverManagerDataSource.java:253)
at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:234)
at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:113)
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:79)
... 10 more

解决方案 »

  1.   

    小弟对spring不是很懂,请大哥大姐赐教。我想可能是对数据库访问过于频繁,连接没有管理好。但是又不知道怎么弄
      

  2.   


    唉,没人回答,自己弄出来了。
    我把spring jdbc的配置中
    <bean id="springDSN"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName"
    value="com.microsoft.sqlserver.jdbc.SQLServerDriver">
    </property>
    改为
    <bean id="springDSN"
    class="org.springframework.jdbc.datasource.SingleConnectionDataSource">
    <property name="driverClassName"
    value="com.microsoft.sqlserver.jdbc.SQLServerDriver">
    </property>
    OK。再也不报错了。
      

  3.   

    java.net.BindException: Address already in use: connect
    .. 连接过多
      

  4.   

    嗯。好了,比较一下两个类。给大家分享一下:
    SingleConnectionDataSource
    这个SmartDataSource的实现封装了单个在使用后不会关闭的连接。 所以很明显,它没有多线程的能力。如果客户端代码想关闭这个认为是池管理的连接,比如使用持久化工具的时候, 需要将suppressClose设置成true。这样会返回一个禁止关闭的代理来接管物理连接。 需要注意的是,你将无法将不再能将这个连接转换成本地Oracle连接或者类似的连接。它的主要作用是用来测试。例如,它可以很容易的让测试代码脱离应用服务器测试,而只需要一个简易的JNDI环境。 和DriverManagerDataSource相反,它在所有的时候都重用一个连接, 以此来避免建立物理连接过多的消耗。

    DriverManagerDataSource
    这个SmartDataSource的实现通过bean的属性配置JDBC驱动, 并每次都返回一个新的连接。它对于测试或者脱离J2EE容器的独立环境都是有用的, 它可以作为不同的ApplicationContext中的数据源bean, 也可以和简易的JNDI环境一起工作。被认为是池管理的Connection.close()操作 的调用只会简单的关闭连接,所以任何使用数据源的持久化代码都可以工作。 
    这样大家应该知道为什么不抛出 java.net.BindException: Address already in use: connect异常了吧