Java实现数据库断线重连

最近写了很多硬件设备的采集程序,由于数据的分析和页面的展示都是通过数据库服务器上的oracle数据库计算并且发送到前台可视化显示的。这其中就有个问题就是,一旦数据库服务器停电了或者宕机了,那么必须得有人手动重启应用服务器的程序。所以这里需要有增加一个断线重连的功能。
直接上代码


Java实现数据库断线重连_第1张图片
image.png

如上图所示,OracleWriter是接收并解析好的数据,insert到数据库中,在这个类的构造方法中通过scheduleAtFixedRate方法每隔十秒调用一下MonitorThread线程的逻辑,我们来主要看一下MonitorThread这个监控类。

package com.junlai.wifi.server;

import org.apache.log4j.Logger;

import java.sql.*;

public class MonitorThread implements Runnable {

    private static final Logger logger = Logger.getLogger(MonitorThread.class);

    private String url;

    private String user;

    private String password;


    public MonitorThread( String url, String user, String password) {
        this.url = url;
        this.user = user;
        this.password = password;
    }

    public void run() {
        try {
            System.out.println("MonitorThread~~~~~~~~~~~~~!!!!");
            String sql = "select 1 from dual";
            Statement statement = OracleWriter.conn.createStatement();
            ResultSet resultSet = statement.executeQuery(sql);
            /*while (resultSet.next()) {

            }*/
            if (resultSet != null) {
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    e.printStackTrace();

                }
            }
            if (statement != null) {
                try {
                    statement.close();
                } catch (SQLException e) {
                    e.printStackTrace();

                }
            }

        } catch (Exception e) {
            System.out.println("捕获到了异常!!!!!!!!!!!!");
            e.printStackTrace();
            logger.error("数据库连接中断,尝试重连" + e.getMessage());
            try {
                OracleWriter.conn = null;
                OracleWriter.conn = DriverManager.getConnection(url, user, password);
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        }

    }
}


package com.junlai.wifi.server;

import org.apache.log4j.Logger;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.concurrent.*;

/**
 * Created by liz on 2018/7/9.
 */
public class OracleWriter implements WriterInterface{

    private static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private static final Logger logger = Logger.getLogger(OracleWriter.class);

    public static volatile Connection conn = null;

    private ScheduledExecutorService oraclePool = Executors.newScheduledThreadPool(1);

    public static final int ORACLE_MONITOR_PERIOD = 10;

    public Connection getConn() {
        return conn;
    }

    public void setConn(Connection conn) {
        this.conn = conn;
    }

    static {
        try {
            Class.forName("oracle.jdbc.driver.OracleDriver");
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            e.printStackTrace();
        }
    }

    public OracleWriter(String url, String user, String password) {
        try {
            conn = DriverManager.getConnection(url,user,password);
            conn.setAutoCommit(true);
            oraclePool.scheduleAtFixedRate(new MonitorThread(url,user,password),0,ORACLE_MONITOR_PERIOD, TimeUnit.SECONDS);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            e.printStackTrace();
        }
    }
}

思路

1.通过"select 1 from dual"来检测数据库是否还正常。(如果正常则应该返回"1")
2.如果服务器这个时候已经断了,则直接捕获到异常。
3.为了高效只有一个static的Connection连接,不主动关闭。但是在异常中我们手动的将OracleWriter的conn的连接对象设为null(我尝试了close,直接报错了。)等待GC把他回收,然后再把新创建的conn赋值给OracleWriter的conn。
4.大功告成,很简单吧,经了解到常见的数据库连接池的断线重连的实现原理也类似是这样。

你可能感兴趣的:(Java实现数据库断线重连)