Java實(shí)現(xiàn)數(shù)據(jù)庫(kù)斷線重連

最近寫(xiě)了很多硬件設(shè)備的采集程序,由于數(shù)據(jù)的分析和頁(yè)面的展示都是通過(guò)數(shù)據(jù)庫(kù)服務(wù)器上的oracle數(shù)據(jù)庫(kù)計(jì)算并且發(fā)送到前臺(tái)可視化顯示的。這其中就有個(gè)問(wèn)題就是,一旦數(shù)據(jù)庫(kù)服務(wù)器停電了或者宕機(jī)了,那么必須得有人手動(dòng)重啟應(yīng)用服務(wù)器的程序。所以這里需要有增加一個(gè)斷線重連的功能。
直接上代碼


image.png

如上圖所示,OracleWriter是接收并解析好的數(shù)據(jù),insert到數(shù)據(jù)庫(kù)中,在這個(gè)類(lèi)的構(gòu)造方法中通過(guò)scheduleAtFixedRate方法每隔十秒調(diào)用一下MonitorThread線程的邏輯,我們來(lái)主要看一下MonitorThread這個(gè)監(jiān)控類(lèi)。

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("數(shù)據(jù)庫(kù)連接中斷,嘗試重連" + 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.通過(guò)"select 1 from dual"來(lái)檢測(cè)數(shù)據(jù)庫(kù)是否還正常。(如果正常則應(yīng)該返回"1")
2.如果服務(wù)器這個(gè)時(shí)候已經(jīng)斷了,則直接捕獲到異常。
3.為了高效只有一個(gè)static的Connection連接,不主動(dòng)關(guān)閉。但是在異常中我們手動(dòng)的將OracleWriter的conn的連接對(duì)象設(shè)為null(我嘗試了close,直接報(bào)錯(cuò)了。)等待GC把他回收,然后再把新創(chuàng)建的conn賦值給OracleWriter的conn。
4.大功告成,很簡(jiǎn)單吧,經(jīng)了解到常見(jiàn)的數(shù)據(jù)庫(kù)連接池的斷線重連的實(shí)現(xiàn)原理也類(lèi)似是這樣。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容