`
lbyzx123
  • 浏览: 478016 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

jdbc连接Software caused connection abort: socket write error

    博客分类:
  • J2EE
 
阅读更多
我使用jdbc开发了个j2ee小系统,数据库用的是mysql5,部署的服务器为tomcat;
一般情况下没有什么问题,在开发中也是偶然发现,我的电脑没有关,部署的服务器一直运行着,
长时间没有使用,第二天一来再点击系统,则后台出现如下异常:

 

- Communications link failure due to underlying exception: 

** BEGIN NESTED EXCEPTION ** 

java.net.SocketException
MESSAGE: Software caused connection abort: socket write error

STACKTRACE:

java.net.SocketException: Software caused connection abort: socket write error
 at java.net.SocketOutputStream.socketWrite0(Native Method)
 at java.net.SocketOutputStream.socketWrite(Unknown Source)
 at java.net.SocketOutputStream.write(Unknown Source)
 at java.io.BufferedOutputStream.flushBuffer(Unknown Source)
 at java.io.BufferedOutputStream.flush(Unknown Source)
 at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:2744)
 at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1612)
 at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1723)
 at com.mysql.jdbc.Connection.execSQL(Connection.java:3277)
 at com.mysql.jdbc.Statement.executeUpdate(Statement.java:1402)
 at com.mysql.jdbc.Statement.executeUpdate(Statement.java:1317)
** END NESTED EXCEPTION **

Last packet sent to the server was 0 ms ago.
在重启服务器后,一切又正常运行。

从以上异常可以看出,是tomcat服务器与mysql数据库服务器之间已失去连接。

查找相关资料,发现原因如下:

tomcat与数据库建立长连接以后,mysql会建立一个Socket与tomcat通信。mysql建立的Socket
有个timeout时间(超时时间),它的默认值是3600*8(28800),若改连接在8个小时内没有操作
的话,mysql会断开该连接,而tomcat中Connection并不知道远程Socket已关闭,也没有更新自
己的连接状态。

解决办法:在判断Connection没有关闭并且不等于null的时候,通过一个简单的sql操作,判断连
接是否超时,如果超时的话重新建立连接,如果没有超时返回原来的连接。

示例代码如下:
 
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.apache.log4j.Logger;

public class DbConnection {

 private static Logger LOG = Logger.getLogger(DbConnection.class);

 private static Connection singleConnect = null;

 public static Connection getSingleConnection() {
  try {
   if (singleConnect != null && !singleConnect.isClosed()) {
    /**
     * MySQL数据库Socket超时(timeout)是3600*8,即超过8小时,数据库会断开外部的连接,而外部连接的状态没更新
     */
    Statement pingStatement = null;
    ResultSet pingResultSet = null;
    try {
     pingStatement = singleConnect.createStatement();
     pingResultSet = pingStatement.executeQuery("select 1");
    } catch (Exception e) {
     connectionSingle();
    } finally {
     if (pingResultSet != null) {
      pingResultSet.close();
     }
     if (pingStatement != null) {
      pingStatement.close();
     }
    }
    return singleConnect;
   } else {
    connectionSingle();
    return singleConnect;
   }
  } catch (SQLException e) {
   LOG.error(e.getMessage());
   return null;
  }
 }

 private static void connectionSingle() {
  try {
   LOG.info("connectionBase is called");
   if (singleConnect != null && !singleConnect.isClosed()) {
    singleConnect.close();
    singleConnect = null;
   }
   Class.forName("com.mysql.jdbc.Driver");
   singleConnect = DriverManager
     .getConnection(
       "jdbc:mysql://127.0.0.1:3306/anxiesoft?useUnicode=true&characterEncoding=UTF-8&noAccessToProcedureBodies=true",
       "mysql", "passord");
   singleConnect.setAutoCommit(false);
   LOG.info("connectionBase finished");
  } catch (ClassNotFoundException cnfe) {
   LOG.error(new java.util.Date().toString()
     + " database driver not found:" + cnfe.getMessage());
  } catch (SQLException sqle) {
   LOG.error(new java.util.Date().toString()
     + " database connect error:" + sqle.getMessage());
   connectionSingle();
  }
 }
}


 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics