1. ホーム
  2. マイスル

MySQLで「MySQLNonTransientConnectionException」エラー発生

2022-02-27 07:32:05

MySQLNonTransientConnectionException"は、jdbcを使用してmysqlデータベースに接続するときに報告されます。

JDBCTest.javaのコードです。

public class JDBCTest {
    public static void main(String[] args) throws Exception {
        Connection connection = null;
        PreparedStatement prepareStatement = null;
        ResultSet rs = null;

        try {
            // Load the driver
            Class.forName("com.mysql.jdbc.Driver");
            // Get the connection
            String url = "jdbc:mysql://localhost:3306/demo";
            String user = "root";
            String password = "xxxxxxx";
            connection = DriverManager.getConnection(url, user, password);
            // Get the statement, preparedStatement
            String sql = "select * from tb_user where id=? ";
            prepareStatement = connection.prepareStatement(sql);
            // Set the parameters
            prepareStatement.setLong(1, 1l);
            // execute the query
            rs = prepareStatement.executeQuery();
            // Process the result set
            while (rs.next()) {
                System.out.println(rs.getString("userName"));
                System.out.println(rs.getString("name"));
                System.out.println(rs.getInt("age"));
                System.out.println(rs.getDate("birthday"));
            }
        } finally {
            // Close the connection and release the resources
            if (rs ! = null) {
                rs.close();
            }
            if (prepareStatement ! = null) {
                prepareStatement.close();
            }
            if (connection ! = null) {
                connection.close();
            }
        }
    }
}

Baiduの後、ある人は、接続されたmysqlデータベースがバージョン8.0であり、プロジェクトが使用するcom.mysql.jdbc.driverドライバーパッケージがバージョン5.1であるため、プロジェクトのドライバーバージョンを8.0.11に変更すると解決すると言いました。

そこで、com.mysql.jdbc.Driverのバージョンを8.0.11に変更し、コードを再実行すると、エラーが報告されます。

クラス`com.mysql.jdbc.Loading'をロードしています。これは非推奨です。新しいドライバクラスは`com.mysql.cj.jdbc.Jdbc'です。 ドライバはSPI経由で自動的に登録されるため、ドライバクラスを手動で読み込む必要は通常ありません。
Thu May 28 10:34:56 CST 2020 WARN: MySQL 5.5.45+, 5.6.26+, 5.7.6+ の要件によると、明示的なオプションが設定されていない場合、SSL 接続はデフォルトで確立されなければなりません。Y <スパン useSSL=falseを設定して明示的にSSLを無効にするか、useSSL=trueを設定してサーバー証明書検証用のトラストストアを提供する必要があります。
このエラーメッセージは `com.mysql.jdbc.Driver' が非推奨で、新しいドライバは com.mysql.cj.jdbc.Driver であることを意味します。MySQL 5.5.45+, 5.6.26+, 5.7.6+ によると、明示的なオプションが設定されていない場合、デフォルトでSSL接続を確立する必要があるそうです。useSSL=falseを設定してSSLを明示的に無効にするか、useSSL=trueを設定してサーバー証明書検証用のトラストストアを提供する必要があります。

JDBCTest.javaを変更します。

/**
 * @author Evan
 */
public class JDBCTest {
    public static void main(String[] args) throws Exception {
        Connection connection = null;
        PreparedStatement prepareStatement = null;
        ResultSet rs = null;

        try {
            // load the driver to com.mysql.cj.jdbc.
            Class.forName("com.mysql.cj.jdbc.Driver");
            // Get the connection, set useSSL=false
            String url = "jdbc:mysql://localhost:3306/ssmdemo?useSSL=false";
            String user = "root";
            String password = "123456";
            connection = DriverManager.getConnection(url, user, password);
            // Get the statement, preparedStatement
            String sql = "select * from tb_user where id=? ";
            prepareStatement = connection.prepareStatement(sql);
            // Set the parameters
            prepareStatement.setLong(1, 1l);
            // execute the query
            rs = prepareStatement.executeQuery();
            // Process the result set
            while (rs.next()) {
                System.out.println(rs.getString("userName"));
                System.out.println(rs.getString("name"));
                System.out.println(rs.getInt("age"));
                System.out.println(rs.getDate("birthday"));
            }
        } finally {
            // Close the connection and release the resources
            if (rs ! = null) {
                rs.close();
            }
            if (prepareStatement ! = null) {
                prepareStatement.close();
            }
            if (connection ! = null) {
                connection.close();
            }
        }
    }
}



変更後、JDBCTest.javaを実行すると、エラー ...................。

スレッド "main" java.sql.SQLException で例外が発生しました。サーバーのタイムゾーン値 'Öйú±ê׼ʱ¼ä' は認識できないか、複数のタイムゾーンを表しています。 タイムゾーン・サポートを利用するには、サーバーまたは JDBC ドライバーのいずれか(serverTimezone 構成プロパティを使用)で、より具体的なタイムゾーン値を使用するように構成する必要があります。
このエラーはタイムゾーンの問題で、データベースはデフォルトで英語、0:00のタイムゾーンでインストールされています。
上記のプロンプトから、サーバーの設定、またはjdbcドライバの接続パラメータをserverTimeZoneで設定することで、特定のタイムゾーンを指定できることが分かります。

(1) JDBCの接続パラメータを設定する。url接続文字列の後に、?serverTimezone=UTCを追加します。

変更したJDBCTest.java。

/**
 * @author Evan
 */
public class JDBCTest {
    public static void main(String[] args) throws Exception {
        Connection connection = null;
        PreparedStatement prepareStatement = null;
        ResultSet rs = null;

        try {
            // load the driver to com.mysql.cj.jdbc.
            Class.forName("com.mysql.cj.jdbc.Driver");
            // Get the connection, set useSSL=false,serverTimezone=UTC
            String url = "jdbc:mysql://localhost:3306/ssmdemo?useSSL=false&serverTimezone=UTC";
            String user = "root";
            String password = "123456";
            connection = DriverManager.getConnection(url, user, password);
            // Get the statement, preparedStatement
            String sql = "select * from tb_user where id=? ";
            prepareStatement = connection.prepareStatement(sql);
            // Set the parameters
            prepareStatement.setLong(1, 1l);
            // execute the query
            rs = prepareStatement.executeQuery();
            // Process the result set
            while (rs.next()) {
                System.out.println(rs.getString("userName"));
                System.out.println(rs.getString("name"));
                System.out.println(rs.getInt("age"));
                System.out.println(rs.getDate("birthday"));
            }
        } finally {
            // Close the connection and release the resources
            if (rs ! = null) {
                rs.close();
            }
            if (prepareStatement ! = null) {
                prepareStatement.close();
            }
            if (connection ! = null) {
                connection.close();
            }
        }
    }
}


(2)MySQLのデータベース設定を変更する。

time_zone%」のような変数を表示する。

mysql> show variables like "%time_zone%"です。
+------------------+--------+
| 変数名|値
+------------------+--------+
| システムタイムゾーン|||
| タイムゾーン|SYSTEM||||。
+------------------+--------+

-東部8時(北京時間)に設定。
global time_zone='+8:00'を設定します。

mysql> set global time_zone='+8:00';
クエリ OK、影響を受ける行数は 0 です (0.00 秒)

設定後、コマンドラインを再度開き、mysql,query timeに移動します。

mysql> show variables like "%time_zone%";
+------------------+--------+
| 変数名|値
+------------------+--------+
| システムタイムゾーン|||
| 時間帯|+08:00|の場合
+------------------+--------+
2列セット、警告1回(0.01秒)

この時点では、jdbcがserverTimezone=UTCを追加しなくても、問題なく動作します。