失樂(lè)園

          技術(shù)之路

          BlogJava 聯(lián)系 聚合 管理
            19 Posts :: 44 Stories :: 40 Comments :: 0 Trackbacks

          常用鏈接

          留言簿(2)

          隨筆檔案

          文章檔案




          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

            常見(jiàn)問(wèn)題和解決方案

            對(duì)于MySQL Connector/J用戶,會(huì)遇到一些常見(jiàn)的共同問(wèn)題。在本節(jié)中,介紹了它們的癥狀和相應(yīng)的解決方法。 關(guān)于更進(jìn)一步的信息,請(qǐng)參見(jiàn)“支持”一節(jié)。

            問(wèn)題:

            當(dāng)我嘗試用MySQL Connector/J連接到數(shù)據(jù)庫(kù)時(shí),遇到下述異常:

            SQLException: Server configuration denies access to data source

            SQLState: 08001

            VendorError: 0

            出現(xiàn)了什么問(wèn)題? 使用MySQL命令行客戶端時(shí),連接良好。

            回答:

            MySQL Connector/J必須使用TCP/IP套接字來(lái)連接MySQL,原因在于Java不支持Unix Domain套接字。因此,當(dāng)MySQL Connector/J連接到MySQL時(shí),MySQL服務(wù)器的安全管理器將使用其授權(quán)表判斷是否允許連接。必須添加授權(quán)才能允許該操作。下面給出了一個(gè)執(zhí)行該操作的示例(但并非最安全的)。

            從mysql命令行客戶端以能夠授權(quán)的用戶身份登錄,并發(fā)出下述命令:

            GRANT ALL PRIVILEGES ON [dbname].* to

            '[user]'@'[hostname]' identified by

            '[password]'

            用你的數(shù)據(jù)庫(kù)名稱替換[dbname],用用戶名替換[user],用MySQL Connector/J將連接的主機(jī)替換[hostname],并用打算使用的密碼替換[password]。注意,對(duì)于從本地主機(jī)進(jìn)行連接的主機(jī)名部分,RedHat Linux將失敗。在這種情況下,對(duì)于[hostname]值,需要使用“localhost.localdomain”。隨后,發(fā)出FLUSH PRIVILEGES命令。

            注釋:

            除非添加了“--host”標(biāo)志,并為主機(jī)使用了不同于“localhost”的其他設(shè)置,否則將無(wú)法使用mysql命令行客戶端測(cè)試連通性。如果使用了特殊的主機(jī)名“localhost”,mysql命令行客戶端將使用Unix域套接字。如果正在測(cè)試與“localhost”的連通性,請(qǐng)使用 “127.0.0.1”作為主機(jī)名。

            警告

            如果你不了解“GRANT”命令是干什么的,或不了解該命令的工作方式,在嘗試更改權(quán)限之前,請(qǐng)閱讀MySQL手冊(cè)中的 一般安全事宜以及MySQL訪問(wèn)權(quán)限體系一節(jié)。

            如果在MySQL中不恰當(dāng)?shù)馗牧藱?quán)限和許可,可能會(huì)使服務(wù)器不會(huì)具有最佳的安全性能。

            問(wèn)題:

            我的應(yīng)用程序拋出SQLException“無(wú)恰當(dāng)?shù)尿?qū)動(dòng)程序”。為什么會(huì)出現(xiàn)該情況?

            回答:

            出現(xiàn)了兩種情況之一。或是1驅(qū)動(dòng)程序未位于你的CLASSPATH中(請(qǐng)參見(jiàn)前面的“安裝部分”),或是URL格式不正確(請(qǐng)參見(jiàn)用MySQL Connector/J開(kāi)發(fā)應(yīng)用程序)。

            問(wèn)題:

            當(dāng)我試圖在Java程序或應(yīng)用程序中使用MySQL Connector/J時(shí),遇到類(lèi)似下面的異常:

            SQLException: 無(wú)法連接到host:3306上的MySQL服務(wù)器。

            在你嘗試連接的機(jī)器/端口上是否有正在運(yùn)行的MySQL服務(wù)器?

            (java.security.AccessControlException)

            SQLState: 08S01

            VendorError: 0

            回答:

            或許是因?yàn)槟阏谶\(yùn)行Applet,你的MySQL服務(wù)器是采用“--skip-networking”選項(xiàng)集安裝的;或許是因?yàn)镸ySQL服務(wù)器位于防火墻之后。

            Applet僅能使網(wǎng)絡(luò)連接返回運(yùn)行Web服務(wù)器的機(jī)器,該Web服務(wù)器提供了用于Applet的.class文件。這意味著,要想使其工作, MySQL 必須運(yùn)行在相同的機(jī)器上(或必須使某類(lèi)端口重定向)。這還意味著,你無(wú)法通過(guò)你的本地文件系統(tǒng)來(lái)測(cè)試Java程序,你必須將它們放在Web服務(wù)器上。

            MySQL Connector/J僅能使用TCP/IP與MySQL進(jìn)行通信,這是因?yàn)镴ava不支持Unix域套接字。如果MySQL是用“--skip-networking”標(biāo)志啟動(dòng)的,或采用了防火墻,TCP/IP與MySQL的通信可能會(huì)受到影響。

            如果MySQL是用“--skip-networking”選項(xiàng)集啟動(dòng)的(例如MySQL服務(wù)器的Debian Linux包即用于該目的),需要在文件/etc/mysql/my.cnf或/etc/my.cnf中將其注釋掉。當(dāng)然,my.cnf文件也可能位于 MySQl服務(wù)器的“data”目錄下或其他地方(取決于系統(tǒng)中MySQL的編譯方式)。MySQL AB創(chuàng)建的二進(jìn)制文件總會(huì)在查找/etc/my.cnf和[datadir]/my.cnf。如果為MySQL服務(wù)器部署了防火墻,需要對(duì)防火墻進(jìn)行配置,允許從運(yùn)行Java代碼的主機(jī)在MySQL監(jiān)聽(tīng)的端口上(默認(rèn)為3306)建立與 MySQL服務(wù)器的TCP/IP連接。

            問(wèn)題:

            I我的小服務(wù)程序/應(yīng)用程序白天工作良好,但在晚上卻停止工作。

            回答:

            不工作時(shí)間超過(guò)8小時(shí)后,MySQL關(guān)閉了連接。你或許需要使用能處理失效連接的連接池,或使用“autoReconnect”參數(shù)(請(qǐng)參見(jiàn)用MySQL Connector/J開(kāi)發(fā)應(yīng)用程序)。

            此外,你應(yīng)在應(yīng)用程序中俘獲 SQLException并處理它們,而不是在應(yīng)用程序退出前一直傳播它們,這是1個(gè)好的編程習(xí)慣。在查詢處理過(guò)程中遇到網(wǎng)絡(luò)連通性方面的問(wèn)題時(shí), MySQL Connector/J會(huì)將SQLState(參見(jiàn)APIDOCS中的java.sql.SQLException.getSQLState())設(shè)置為 “08S01”。隨后,應(yīng)用程序代碼將嘗試再次連接到MySQL。

            在下面的示例(simplistic)中,給出了能夠處理這類(lèi)異常的代碼:

            重試邏輯的事務(wù)示例

            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 41000 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) || "41000".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));
              }

            問(wèn)題:

            我正嘗試使用JDBC-2.0可更新結(jié)果集,但遇到異常,說(shuō)我的結(jié)果集不可更新。

            回答:

            由于MySQL沒(méi)有行ID,MySQL Connector/J僅能更新來(lái)自查詢且位于有至少一個(gè)主鍵的表上的結(jié)果集,查詢必須選擇所有的主鍵,而且查詢即能作用在1個(gè)表上(即不存在聯(lián)合)。在JDBC規(guī)范中給出了這方面的介紹。
          posted on 2008-07-27 20:22 狄浩 閱讀(707) 評(píng)論(0)  編輯  收藏

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 泌阳县| 嘉峪关市| 哈尔滨市| 建昌县| 吉安市| 慈溪市| 东乡| 绵阳市| 朝阳区| 湛江市| 行唐县| 咸丰县| 观塘区| 西丰县| 罗定市| 高邑县| 宝清县| 鄂伦春自治旗| 家居| 乌海市| 吴堡县| 治多县| 称多县| 丹阳市| 凌源市| 宁夏| 阜城县| 门源| 浪卡子县| 遵义县| 德清县| 石林| 马尔康县| 张家界市| 微山县| 五指山市| 林西县| 名山县| 黄骅市| 夹江县| 延川县|