简体   繁体   English

Spring 2.5无法获得JDBC连接

[英]Spring 2.5 Could not get JDBC Connection

I'm using spring 2.5 SimpleJdbcTemplate to access MySQL db. 我正在使用spring 2.5 SimpleJdbcTemplate来访问MySQL数据库。 When I try to access the DB too often(using Quartz to access it every minute) i get this stack trace: 当我尝试经常访问数据库(使用Quartz每分钟访问它)时,我得到了这个堆栈跟踪:

org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot create PoolableConnectionFactory (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 org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:82)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:382)
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:458)
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:466)
    at org.springframework.jdbc.core.JdbcTemplate.queryForList(JdbcTemplate.java:497)
    at org.springframework.jdbc.core.simple.SimpleJdbcTemplate.queryForList(SimpleJdbcTemplate.java:223)
    at com.db.timexis.dao.UserDaoJdbc.getListOfAllUsers(UserDaoJdbc.java:137)
    at com.db.timexis.service.AuthServiceImpl.getListOfAllUsers(AuthServiceImpl.java:77)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
    at $Proxy0.getListOfAllUsers(Unknown Source)
    at com.mail.timexis.ReminderBean.execute(ReminderBean.java:25)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:276)
    at org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean$MethodInvokingJob.executeInternal(MethodInvokingJobDetailFactoryBean.java:260)
    at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:86)
    at org.quartz.core.JobRunShell.run(JobRunShell.java:216)
    at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:549)
Caused by: org.apache.commons.dbcp.SQLNestedException: Cannot create PoolableConnectionFactory (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 org.apache.commons.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1225)
    at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:880)
    at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:113)
    at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:79)
    ... 30 more
Caused by: 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(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:409)
    at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1122)
    at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2260)
    at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:787)
    at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:49)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:409)
    at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:357)
    at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:285)
    at org.apache.commons.dbcp.DriverConnectionFactory.createConnection(DriverConnectionFactory.java:38)
    at org.apache.commons.dbcp.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:294)
    at org.apache.commons.dbcp.BasicDataSource.validateConnectionFactory(BasicDataSource.java:1247)
    at org.apache.commons.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1221)
    ... 33 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The driver was unable to create a connection due to an inability to establish the client portion of a socket.

This is usually caused by a limit on the number of sockets imposed by the operating system. This limit is usually configurable. 

For Unix-based platforms, see the manual page for the 'ulimit' command. Kernel or system reconfiguration may also be required.

For Windows-based platforms, see Microsoft Knowledge Base Article 196271 (Q196271).
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:409)
    at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1122)
    at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:344)
    at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2181)
    ... 46 more
Caused by: java.net.BindException: Address already in use: connect
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
    at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
    at java.net.Socket.connect(Socket.java:519)
    at java.net.Socket.connect(Socket.java:469)
    at java.net.Socket.<init>(Socket.java:366)
    at java.net.Socket.<init>(Socket.java:209)
    at com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:256)
    at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:293)
    ... 47 more

The code executed every minute: 每分钟执行的代码:

public void execute() {
        List<User> regularUsers = null;
        try {
            // get all regular users
            ApplicationContext ctx = new ClassPathXmlApplicationContext(
                    "applicationContext.xml");
            AuthService authService = (AuthService) ctx.getBean("authService");

            regularUsers = authService.getListOfAllUsers();
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            if (regularUsers != null) {
                for (User u : regularUsers) {
                    if (u.getEmail().matches("^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*(\\.[_A-Za-z0-9-]+)")) {
                        mailSender.sendMailReminder(u.getEmail(),
                                u.getFirstName());
                        // log mail sending
                        Date date = Calendar.getInstance().getTime();
                        SimpleDateFormat sdf = new SimpleDateFormat(
                                "yyyy/MM/dd HH:mm:ss");
                        String strDate = sdf.format(date);
                        System.out.println(strDate + "Reminder mail send...");
                        // log mail sending
                    }else{
                        System.out.println("invalid mail address");
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

It's executed every minute for testing purposes. 它每分钟执行一次以进行测试。 It will be executed once a week in the future. 它将在未来每周执行一次。

My DBCP propertyes: 我的DBCP属性:

jdbc.maxActive=15
jdbc.maxIdle=10
jdbc.minIdle=5
jdbc.maxWait=5000
jdbc.validationQuery=select 1
jdbc.timeBetweenEvictionRunsMillis=1000
jdbc.numTestsPerEvictionRun=10
jdbc.minEvictableIdleTimeMillis=1200000

The data base is accessable trough the command line. 可以通过命令行访问数据库。

Note that you create a new instance of application context each time your method is invoked, and don't close it. 请注意,每次调用方法时都会创建一个新的应用程序上下文实例,并且不要关闭它。 It means that resources allocated by beans decalred in this context (for example, connections created by connection pool) are not released. 这意味着在此上下文中由bean分配的资源(例如,由连接池创建的连接)不会被释放。

Typically you need to create application context only once during startup of your application and close it upon shutdown, so I suggest you to implement it this way. 通常,您需要在应用程序启动期间仅创建一次应用程序上下文,并在关闭时关闭它,因此我建议您以这种方式实现它。

If you actullay need to create a new application context each time you call that method, don't forget to close() it at the end of the method (in finally block for reliability). 如果你需要每次调用该方法时都需要创建一个新的应用程序上下文,不要忘记在方法结束时close()finally一块为了可靠性)。

Also note that you should declare an appropriate destroy-method for your connection pool bean in order to release resources when context is being closed. 另请注意,您应该为连接池bean声明一个适当的destroy-method ,以便在关闭上下文时释放资源。

The main exception is "java.net.BindException: Address already in use: connect". 主要的例外是“java.net.BindException:Address in in use:connect”。 It seems you have connection pool leak. 看来你有连接池泄漏。 Are you sure that every connection is closed after usage? 您确定每个连接在使用后都已关闭吗? Please check it. 请检查一下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM