MySQL 連接池常常會被用于高并發的 Web 項目中,目的就是為了重復利用連接,避免每次都要獲取和釋放連接,從而提高效率。不過,有時候 MySQL 連接池會出現異常,需要進行重連。
public class MysqlDataSource { private static final int DEFAULT_RECONNECT_SECONDS = 10; private long lastConnectTime; private long lastReconnectedTime; private String url; private String username; private String password; private int maxPoolSize = 10; private volatile boolean released; private volatile boolean paused; private ListidleConnections = new ArrayList (); private List activeConnections = new ArrayList (); public synchronized Connection getConnection() throws SQLException { if (released) { throw new SQLException("Connection pool has been released."); } if (idleConnections.size() >0) { Connection conn = idleConnections.remove(0); if (conn.isValid(1)) { activeConnections.add(conn); return conn; } } if (activeConnections.size()< maxPoolSize) { Connection conn = createConnection(); activeConnections.add(conn); return conn; } throw new SQLException("Connection pool is full."); } private Connection createConnection() throws SQLException { try { Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection(url, username, password); return conn; } catch (ClassNotFoundException e) { throw new SQLException("Cannot find com.mysql.jdbc.Driver"); } } public synchronized void releaseConnection(Connection conn) { activeConnections.remove(conn); if (idleConnections.size()< maxPoolSize) { idleConnections.add(conn); } else { closeConnection(conn); } } private void closeConnection(Connection conn) { try { conn.close(); } catch (SQLException e) { // ignore } } private void reconnect() throws SQLException { if (lastReconnectedTime + DEFAULT_RECONNECT_SECONDS * 1000 >System.currentTimeMillis()) { return; } synchronized (this) { if (lastReconnectedTime + DEFAULT_RECONNECT_SECONDS * 1000 >System.currentTimeMillis()) { return; } lastReconnectedTime = System.currentTimeMillis(); } List reconnected = new ArrayList<>(); try { for (Connection conn : idleConnections) { if (!conn.isValid(1)) { Connection newConn = createConnection(); reconnected.add(newConn); idleConnections.set(idleConnections.indexOf(conn), newConn); } } } finally { idleConnections.addAll(reconnected); } } }
在上述的代碼中,能夠看到 reconnect() 方法,這個方法主要是用于重連的。當 idle 連接池中的連接發生了失效時,就會通過 createConnection() 方法進行重連。
在高并發的情況下,MySQL 連接池異常重連的問題是比較常見的。如果不及時重連,就會影響服務的正常運行。因此,對于 MySQL 連接池異常重連,我們需要及時定位和解決問題。
上一篇mysql 連接池中間件
下一篇css行自動居中對齊