java - Spring 2.5 无法获取 JDBC 连接

标签 java mysql spring apache-commons-dbcp

我正在使用 spring 2.5 SimpleJdbcTemplate 访问 MySQL 数据库。当我尝试过于频繁地访问数据库时(每分钟使用 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

每分钟执行的代码:

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();
        }
    }

出于测试目的,它每分钟执行一次。以后每周执行一次。

我的 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

可以通过命令行访问数据库。

最佳答案

请注意,每次调用您的方法时,您都会创建一个新的应用程序上下文实例,并且不要关闭它。这意味着在此上下文中 decalred 的 bean 分配的资源(例如,连接池创建的连接)不会被释放。

通常您只需要在应用程序启动期间创建一次应用程序上下文并在关闭时关闭它,所以我建议您以这种方式实现它。

如果您实际上需要在每次调用该方法时创建一个新的应用程序上下文,请不要忘记在方法结束时close()它(在finally block 可靠性)。

另请注意,您应该为连接池 bean 声明一个适当的destroy-method,以便在上下文关闭时释放资源。

关于java - Spring 2.5 无法获取 JDBC 连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9065946/

相关文章:

java - 如何查找本地IP地址

Spring LDAP - 如何管理编码(SHA)密码

java - 创建正则表达式匹配数组

java - 我应该使用 Thread.sleep 对其他程序友好吗?

php - 如何按每个主题显示我的数据库文件

php - MYsql查询和DB帮助

SVN结帐后spring webapp项目无法运行

java - spring-boot - 哪段代码实际为 springMVC 注册了调度程序 servlet?

java - Android Studio - 使用 Volley 从服务器获取 JSON 数据

mysql - JSF 编码 UTF-8?