無料PHPプログラム

MySQL 5.1 リファレンスマニュアル :: 24 MySQL コネクタ :: 24.4 MySQL Connector/J :: 24.4.5 Connector/J に関する注記とヒント :: 24.4.5.3 よくある問題と解決法
« 24.4.5.2 J2EE および 他の Java フレームワークで Connector/J を使用する

24.4.6 Connector/J のサポート »
Section Navigation      [Toggle]
  • 24.4.5 Connector/J に関する注記とヒント
  • 24.4.5.1 JDBC の基本コンセプト
  • 24.4.5.2 J2EE および 他の Java フレームワークで Connector/J を使用する
  • 24.4.5.3 よくある問題と解決法

24.4.5.3. よくある問題と解決法

MySQL Connector/J のユーザがよく直面する問題がいくつかあります。このセクションでは、それらの兆候と解決法を説明します。

Questions

  • 24.4.5.3.1: MySQL Connector/J でデータベースに接続しようとすると、次の例外が出ます :

    SQLException: Server configuration denies access to data source
    SQLState: 08001
    VendorError: 0

    これはなんでしょうか ?MySQL コマンドライン クライアントとは問題なく接続できます。

  • 24.4.5.3.2: アプリケーションが SQLException 'No Suitable Driver' を投入するのですが、なぜでしょうか?

  • 24.4.5.3.3: アプレットまたはアプリケーションで MySQL Connector/J を使用したいのですが、次に似た例外が出ます :

    SQLException: Cannot connect to MySQL server on host:3306.
    Is there a MySQL server running on the machine/port you
    are trying to connect to?
    
    (java.security.AccessControlException)
    SQLState: 08S01
    VendorError: 0 
  • 24.4.5.3.4: 1 日は問題なく動くのですが、夜の間に停止してしまうサーブレット/アプリケーションがあります。

  • 24.4.5.3.5: JDBC-2.0 の更新可能な結果セットを使おうとすると、その結果セットは更新不可能という例外が出ます。

  • 24.4.5.3.6: Connector/J を使って MySQL サーバに接続できません。接続パラメータが間違っているようです。

Questions and Answers

24.4.5.3.1: MySQL Connector/J でデータベースに接続しようとすると、次の例外が出ます :

SQLException: Server configuration denies access to data source
SQLState: 08001
VendorError: 0

これはなんでしょうか ?MySQL コマンドライン クライアントとは問題なく接続できます。

java は Unix Domain Sockets をサポートしないため、MySQL Connector/J は MySQL への接続に TCP/IP ソケットを使用する必要があります。そのため、MySQL Connector/J が MySQL に接続する場合、MySQL サーバのセキュリティ マネージャはその grant テーブルを使用して、接続が許可されるべきかを決定します。

MySQL サーバに GRANT 文を使用して、これが起きるように、必要なセキュリティ証明書を MySQL サーバに追加する必要があります。詳細は 項12.5.1.3. 「GRANT 構文」 を参照。

注意.? mysql コマンドライン クライアントでの接続のテストは、--host フラグを加え、localhost 以外をホストに使用しなければ作動しません。mysql コマンドライン クライアントは、特別なホスト名 localhost を使っている場合、Unix ドメイン ソケットを使用しません。localhost への接続をテストしている場合、ホスト名に 127.0.0.1 を代わりに使用してください。

注意.? MySQL で権限や許可を不適切に変更すると、サーバが適したセキュリティ プロパティを持たないでインストールされる恐れがありまs。

24.4.5.3.2: アプリケーションが SQLException 'No Suitable Driver' を投入するのですが、なぜでしょうか?

このエラーには 3 つの原因が考えられます :

  • Connector/J driver が CLASSPATH にない。項24.4.2. 「Connector/J のインストール」 参照。

  • 接続 URL のフォーマットが間違っている、または誤った JDBC ドライバを参照している。

  • DriverManager を使用している場合、jdbc.drivers システム プロパティに Connector/J ドライバのロケーションが取り込まれていない。

24.4.5.3.3: アプレットまたはアプリケーションで MySQL Connector/J を使用したいのですが、次に似た例外が出ます :

SQLException: Cannot connect to MySQL server on host:3306.
Is there a MySQL server running on the machine/port you
are trying to connect to?

(java.security.AccessControlException)
SQLState: 08S01
VendorError: 0 

アプレットを起動しているか、MySQL サーバが "--skip-networking" オプション セットとインストールされている、または MySQL サーバの前にファイアウォールがあるということが考えられます。

アプレットは、そのアプレットに .class ファイルをサーブしたウェブ サーバを実行するマシンにだけネットワーク接続を確立し戻すことができます。つまり、これを実行するには、MySQL を同じマシン上で起動する必要があります ( もしくは何らかのポート リダイレクトが必要 ) 。これはまた、ローカル ファイル システムからはアプレットをテストすることができないということで、それらをいつもウェブ サーバにデプロイする必要があります。

Java は Unix ドメイン ソケットをサポートしないので、MySQL Connector/J は TCP/IP を使用して、MySQL とだけ交信することができます。MySQL を "--skip-networking" フラグで起動した場合、またはファイアウォールされている場合は、TCP/IP の MySQL との交信は影響を受けている可能性があります。

MySQL が "--skip-networking" オプション セットと起動された場合 ( 例えば MySQL サーバの Debian Linux パッケージはこれを行いません ) 、file /etc/mysql/my.cnf or /etc/my.cnf でそれをコメントアウトする必要があります。当然、my.cnf file もMySQL サーバの data ディレクトリか他の場所にある場合があります ( MySQL がシステムのためにどのようにコンパイルされたかによる ) 。MySQL AB で作成されたバイナリは常に、/etc/my.cnf and [datadir]/my を調査します。MySQL サーバがファイアウォールされている場合、 MySQL が監視しているポートの MySQL サーバへ Java コードを実行しているホストからの TCP/IP を許可するよう、ファイアウォールを構成する必要があります。( デフォルトでは 3306 ) 。

24.4.5.3.4: 1 日は問題なく動くのですが、夜の間に停止してしまうサーブレット/アプリケーションがあります。

MySQL は、8 時間動きがなければ接続を閉じてしまいます。停滞した接続を扱う接続プールを使用するか、"autoReconnect" パラメータを使用する必要があります ( 項24.4.4.1. 「Connector/J の Driver/Datasource クラス名、URL シンタックス、および構成プロパティ」 参照 ) 。

また、アプリケーションが終了するまでSQLExceptions をプロンプトするより、アプリケーションでキャッチして対処するべきでしょう。プログラミングのよい練習です。MySQL Connector/J は、クエリの処理中にネットワーク接続の問題に直面した場合、SQLState ( APIDOCS 内の java.sql.SQLException.getSQLState() 参照 ) を "08S01" に設定します。アプリケーション コードは、この時点で MySQl への再接続を試行します。

次の ( 単純な ) 例は、これらの例外を扱えるコードはどんな様子かを表しています。

例 24.12. リトライ ロジックとのトランザクション例

public void doBusinessOp() throws SQLException {
    Connection conn = null;
    Statement stmt = null;
    ResultSet rs = null;

    //
    // How many times do you want to retry the transaction
    // (or at least _getting_ a connection)?
    //
    int retryCount = 5;

    boolean transactionCompleted = false;

    do {
        try {
            conn = getConnection(); // assume getting this from a
                                    // javax.sql.DataSource, or the
                                    // java.sql.DriverManager

            conn.setAutoCommit(false);

            //
            // Okay, at this point, the 'retry-ability' of the
            // transaction really depends on your application logic,
            // whether or not you're using autocommit (in this case
            // not), and whether you're using transacational storage
            // engines
            //
            // For this example, we'll assume that it's _not_ safe
            // to retry the entire transaction, so we set retry
            // count to 0 at this point
            //
            // If you were using exclusively transaction-safe tables,
            // or your application could recover from a connection going
            // bad in the middle of an operation, then you would not
            // touch 'retryCount' here, and just let the loop repeat
            // until retryCount == 0.
            //
            retryCount = 0;

            stmt = conn.createStatement();

            String query = "SELECT foo FROM bar ORDER BY baz";

            rs = stmt.executeQuery(query);

            while (rs.next()) {
            }

            rs.close();
            rs = null;

            stmt.close();
            stmt = null;

            conn.commit();
            conn.close();
            conn = null;

            transactionCompleted = true;
        } catch (SQLException sqlEx) {

            //
            // The two SQL states that are 'retry-able' are 08S01
            // for a communications error, and 40001 for deadlock.
            //
            // Only retry if the error was due to a stale connection,
            // communications problem or deadlock
            //

            String sqlState = sqlEx.getSQLState();

            if ("08S01".equals(sqlState) || "40001".equals(sqlState)) {
                retryCount--;
            } else {
                retryCount = 0;
            }
        } finally {
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException sqlEx) {
                    // You'd probably want to log this . . .
                }
            }

            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException sqlEx) {
                    // You'd probably want to log this as well . . .
                }
            }

            if (conn != null) {
                try {
                    //
                    // If we got here, and conn is not null, the
                    // transaction should be rolled back, as not
                    // all work has been done

                    try {
                        conn.rollback();
                    } finally {
                        conn.close();
                    }
                } catch (SQLException sqlEx) {
                    //
                    // If we got an exception here, something
                    // pretty serious is going on, so we better
                    // pass it up the stack, rather than just
                    // logging it. . .

                    throw sqlEx;
                }
            }
        }
    } while (!transactionCompleted && (retryCount > 0));
}

注意.? 接続状態やデータベース状態の情報が破損する危険なしに MySQL サーバに再接続できる安全なメソッドはないので、autoReconnect オプションの使用はお勧めしません。その代わり、プールからの利用可能な接続を使用して、MySQL サーバに接続するアプリケーションを有効にする接続プールを使いましょう。autoReconnect 機能は廃止になり、今後のリリースでは除外される可能性があります。

24.4.5.3.5: JDBC-2.0 の更新可能な結果セットを使おうとすると、その結果セットは更新不可能という例外が出ます。

MySQL は行識別子を持たないため、MySQL Connector/J は、少なくともプライマリ キーをひとつ持つテーブルのクエリからの結果セットしか更新できず、クエリはすべてのプライマリ キーと、テーブルをひとつだけスパンすることができるクエリを選択する必要があります ( 結合はなし ) 。これは JDBC 仕様に概要があります。

この問題は更新可能な結果セットを使用する時にだけ起こり、Connector.J は、各行の一意な参照なしで更新される結果セット内の正しい行を特定することができるとは保証できません。WHERE 句を使って、整合される基準値をそれぞれ特定することのできるテーブルで UPDATE または DELETE 文を使用している場合、テーブルに一意的なフィールドを持つのための必須条件はありません。

24.4.5.3.6: Connector/J を使って MySQL サーバに接続できません。接続パラメータが間違っているようです。

サーバで skip-networking オプションが有効になっていないことを確かめてください。Connector/J は TCP/IP でサーバと通信しなければなりません。名前付きソケットはサポートされていません。また、接続を Firewall や他のネットワーク セキュリティ システムに通さないように注意してください。詳細は 項B.1.2.2. 「Can't connect to [local] MySQL server」 をご覧ください。

Copyright c 1997, 2010, Oracle and/or its affiliates. All rights reserved. Legal Notices
Top / Previous / Next / Up / Table of Contents
© 2010, Oracle Corporation and/or its affiliates

無料CGI PHPスクリプト | 新着情報スクリプト | 営業日カレンダー | PHPマニュアル | MySQLマニュアル | PEARマニュアル

Copyright (c) 2010 jmcodex.com All rights reserved.