• ベストアンサー

コネクションプールについて。

いつもお世話になっております。 MySQLへのコネクションを確保しておく コネクションプールを作成したのですが、 このコネクションプールを利用して Select文を実行した時に 古いデータを取得してくる事があります。 コネクションは一度接続されたら それ以降常時接続し破棄は行なっていません。 その為コネクション内に古い情報が残っているのかなと考え、 これを回避する為には使うたびにコネクションのインスタンスを発行し、使い終わったら破棄しなければならないかという考えに至りました。 しかしそれでは、プールの意味が無くなってしまい本末転倒だと思い煮詰まってしまいました・・・。 お手数ですが、 コネクションプールとはどのように作るのが正しいのか教えていただけないでしょうか?

  • Java
  • 回答数5
  • ありがとう数3

質問者が選んだベストアンサー

  • ベストアンサー
noname#86752
noname#86752
回答No.3

#1です。 コネクションプーリングでは 1.プールからのコネクションの取得 2.コネクションの使用 3.プールへのコネクションの返却 を行います。 commons-dbcpなどではこの返却の処理をcloseメソッドで行います。closeという名前になっていますが、実際にはcloseは行われずプールへの返却が行われます。#2さんがおっしゃってるのはこのことです。 コネクションプーリングを行わないで同じ現象が発生するか確認してください。(もしかしたら手間かもしれませんが・・・) もし、発生しないようなら自作のコネクションプーリングを疑いましょう。 可能なら実績のあるcommons-dbcpなどを使うことをお勧めします。 (気を悪くされるかもしれませんが、実績のあるものを使ったほうが確実ですし、多くの情報を入手できます)

kawakami2005
質問者

お礼

ご丁寧に説明いただきありがとうございます。 今回は既存のプール部品に+αの機能が欲しかった為 自分で作成するにいたりました。 当該プール部品を使用している箇所を よくみたところ Resultsetはcloseしていたのですが Statementはcloseしていなかったようなので Statementのclose処理を追加致しました Statementをcloseしなかったために、 今回のような現象が発生したと考えても よろしいのでしょうか?

その他の回答 (4)

  • covachan
  • ベストアンサー率38% (46/120)
回答No.5

>今回は既存のプール部品に+αの機能が欲しかった為 自分で作成するにいたりました こういった事を容易にする為に継承といったものがあるのではないですか? コネクションプーラーは非常に難しいです。 (コーディングの内容ではなく、動作確認、パフォーマンスの改善等において) 既存のものをエンハンスすることを考えるのが妥当だと考えます。

kawakami2005
質問者

お礼

ご意見ありがとうございます >こういった事を容易にする為に継承といったものがあるのではないですか? はい、全くその通りだと思います。 ですが、今回は諸事情により自作する事になってしまい 見事にハマッてしまった次第です。。。

回答No.4

#2です。 >コネクションのcloseを行わずに >ずっと接続を維持しておくもの 私もこの考えであっています。DBの接続部分は保持されたままの物をコネクションプーリングと言っています。 #3で#1さんが書いていますが、commonsを使用した場合にはcloseメソッドで返却をしているだけです。 本題ですが、文面からして、 1)select 2)DML文を実行 その後 3)1)の再実行 という処理っぽいのですが、1)の情報がどこかで保持されっぱなしになっていないでしょうか? ここで、#3さんが書かれているように、プーリングをしない方法では、どういった動きになるでしょうか?

kawakami2005
質問者

お礼

ご丁寧に説明いただきありがとうございます。 下で#1さんにお答えした通り ひとまずはStatementはclose処理を入れ 様子を見ることにしました。

回答No.2

MySQL4.0 + Tomcat4.0 + commons-dbcp + commons-pool で使用したことがありますが、 問題なく動作いたしてました。 上記の組み合わせでは、一旦終了後(insert,update,delete,select)には、返却を行わないといけませんが、返却(close)していますでしょうか? 又は、トランザクションを自動で実行していて、他セッションで参照しているのではないでしょうか?

kawakami2005
質問者

補足

ご回答ありがとうございます。 今回は自作のコネクションプールを使用しています。 返却とはコネクションのcloseの事でしょうか? それは行っておりません。 コネクションプールとは コネクションのcloseを行わずに ずっと接続を維持しておくもの という認識があったのですが、 そもそも私のその認識が間違っているのでしょうか?

noname#86752
noname#86752
回答No.1

「古いデータを取得してくる」というのは、更新したはずのデータが更新されていないということでしょうか? それと何でコネクションプーリングを行ってますか?(commons?) MySQLは使ったことがないのですが、トランザクションの管理やコミット/ロールバックをきちんと行っているか確認してください。

kawakami2005
質問者

補足

ご回答ありがとうございます。 > 「古いデータを取得してくる」というのは、更新したはずのデータが更新されていないということでしょうか? はい、その通りです。 しかしDBを直接確認すると、データは更新されています。 > それと何でコネクションプーリングを行ってますか? 1時間に数百回のDBアクセスが発生する為です。 > コミット/ロールバックをきちんと行っているか 確認を行いましたが、キチンと行っています。 以上、よろしくお願い致します。

関連するQ&A

  • コネクションプールについて

    コネクションプール有とコネクションプール無でDB接続・切断を繰り返したときに どれくらい差があるか試してみようと思いWebアプリ上(フレームワークにStruts2を使用)で 下記コードを実行してみました。 dbcpConnectメソッド(コネクションプール有) と jdbcConnectメソッド(コネクションプール無) をそれぞれ千回づつループで回して実行してみました。 結果は 【コネクションプール有】実行にかかった時間:157384 ミリ秒 【コネクションプール無】実行にかかった時間:158760 ミリ秒 で大差はありませんでした。 コネクションプールを使用するともう少し早いと思っていたのですがそのようなことはないのでしょうか。 public String test4() { // コネクションプール有の接続 long start = System.currentTimeMillis(); for(int i=0; i< 1000; i++) { dbcpConnect(); } long stop = System.currentTimeMillis(); System.out.println("実行にかかった時間は " + (stop - start) + " ミリ秒です。"); // コネクションプール無の接続 start = System.currentTimeMillis(); for(int i=0; i< 1000; i++) { jdbcConnect(); } stop = System.currentTimeMillis(); System.out.println("実行にかかった時間は " + (stop - start) + " ミリ秒です。"); return "jstl4"; } public void dbcpConnect() { Connection con = null; try{ Context context = new InitialContext(); //DataSource ds = (DataSource)context.lookup("java:comp/env/jdbc/library"); DataSource ds = (DataSource)context.lookup("java:/comp/env/jdbc/dhcpTest"); con = ds.getConnection(); Statement stmt = con.createStatement(); String sql = "SELECT * FROM test.test"; ResultSet rs = stmt.executeQuery(sql); } catch(Exception e) { System.out.println("Error"); } finally { try { con.close(); } catch (SQLException e) { e.printStackTrace(); } } } public void jdbcConnect() { Connection con = null; try{ con = DriverManager.getConnection("jdbc:mysql://localhost", "root", "root"); Statement stmt = con.createStatement(); String sql = "SELECT * FROM test.test"; ResultSet rs = stmt.executeQuery(sql); } catch(Exception e) { System.out.println("Error"); } finally { try { con.close(); } catch (SQLException e) { e.printStackTrace(); } } }

    • ベストアンサー
    • Java
  • すでに接続してあるデータベースについて

    mysqlデータベースにperlで接続する際は、 use DBI; $dsn="DBI:mysql:database=test:host=localhost"; $dbh = DBI->connect($dsn,user,passwd); とし、データベースに接続して、 $sth = DBI->prepare("SELECT * From `table`); ・・・・・・ と続いていくと思いますが、 すでにデータベースに接続(コネクション)していた場合、どのように書けばいいのでしょうか? どなたかよろしくお願いします。

    • ベストアンサー
    • Perl
  • 長男は・ウィルスバスター2001常時起動するのを辞めたら・

    昨年12月にウィルスバスター2001をストールしましたが・・・ それ以来・・重くなり・・フリーズも多くなりました。 大学1年の長男は・ウィルスバスター2001常時起動するのを辞めたら・・怪しげな添付ァイルをを見る時だけ、起動したらいっていますが・・ 私は、ケーブルテレビで常時ネット接続なので・・ファイヤーウォールの機能のあるウィルスバスター2001は常時起動にしたいと思っていますが・・ 快適なネットのためは・ウィルスバスター2001を入れたのに重くなり・・フリーズも多くなるのは本末転倒かも・・とも思います

  • 振込手数料に印紙税を上乗せ?

    郵便局が民営化されてから、3万円以上の振込手数料が大幅アップしたと思います。 民営化されると印紙税の納付義務が発生するから、その分手数料もアップするとどこかでみた記憶があるのですが、これって、本来領収書などの課税文書を発行するほうが負担するものではないのでしょうか?従来の銀行でもやはり印紙税が必要な3万円以上になると手数料の額が違いますよね。 そのために必要な印紙代を利用者に負担させるのは本末転倒で、明らかに税の転嫁のような気がするのですが、いかがなものでしょう。法律上はどのように解釈されるのか知りたいです。

  • 接続プール、またはコネクションプールを教えて下さい。

    「接続プール」、「コネクションプール」について質問があります。 MSDNのサイトで「接続プール」に関するサイトを読んでみましたが難しくてあんまり理解できませんでしたが何となく何ですがDBコネクションを共有して使ってパフォーマンスをあげるっていうのはわかりましたが・・・間違ってたらすみません m(_ _)m 申し訳ありませんがこんな私でも簡単にわかるように説明してくれませんでしょうか? 「接続プール」と「コネクションプール」って同じですか? 開発環境は以下のとおりです。 言語:VB.net2005(ADO.net) DB:SQLServer2005 宜しくお願いします。

  • カーソルエラー

    カーソルエラーについて質問です。 phpからpearを使ってoracleへ接続しています。 バッチ処理で大量にSQL文(SELECT,INSERT,UPDATE)を発行したいのですが、カーソルエラーになってしまいます。 途中の処理でエラーになった場合はロールバックしたい為最後までコミットできません。また、なるべく少ないSQL発行で済むようにプログラムを組み替え済みです。 で、少々手詰まりといった状況なのですが、コミットする以外でカーソルエラーを回避する方法はあるでしょうか? DB設計から見直さないとだめですかね…。

    • 締切済み
    • PHP
  • NINTENDO Wi-Fi コネクション接続について教えてください

    現在、DSのWi-Fi USBコネクションがうまくできているのかよくわかりません。 というのも、ニンテンドのサイトで接続チェックでは必ず接続不可となるのに、DSでは十数回に1度つながります。 (対戦ゲームができました) つながらない場合は、エラーコードが86420になります。 つながらない頻度が高いので、どこかに問題はあると思うのですが、何が問題なのかわからなくて質問しました。 ちなみに、インタネット接続環境は、 Bフレッツ←[ルータ]←有線LAN→[PC]+[NINTENDO USB Wi-Fi コネクタ]→DS ※ルータ/PC間の有線LAN はプライベートネットワークで、PCのIPは、 ルータより割り当てられています。 また、プロバイダに確認したところ、以下の回答をもらいました。 ※結局、原因わからず。 ・マンション共有型の常時接続型インターネット接続サービス ・ファイアウォールでのポートフィルタリング等制限は行なっていな  い ・各接続クライアントには、マンション設置の共有機器のDHCPサーバ  より動的プライベートIPアドレスが自動割り当てされる ・外部への接続時には動的プライベートからグローバルIPアドレスへ変 換 ・1つのグローバルIPアドレスを複数のプライベートアドレスにて共有 ・各クライアントのプライベートIPアドレス、および外部接続用のグ  ローバルIPアドレスは非固定 ・上記のプライベートIPアドレス及びIP変換(IPマスカレード)環境の  為、アプリケーション側の仕様等によっては利用出来ないものが有る PCの環境  OS:WinXP SP2 FW:NortonClientFireWall  ※FWを無効にしてもニンテンドのサイトでの接続チェックは接続不可。  後、インタネット接続の共通を設定しています。 何か、お分かりの方がいらしたら、ご協力お願い致します。

  • チェックボックスのデータを受け取ってMYSQL条件としてセットする

    HTML <input type="checkbox" value="データ1" name="aa[]">データ1      <input type="checkbox" value="データ2" name="aa[]">データ2 PHP <?php =====DB接続省略======== foreach($aa as $val){ //SQL文 $sql = "SELECT NO,SERVISNAME from JOBDATA WHERE SERVISNAME='$val' } //SQLを発行して結果セットを取得します $rst = mysql_query($sql); //取得された結果セットのレコード数を取得・表示します // $body = mysql_num_rows($rst) . " 件のデータがあります。<BR><BR>"; ======DBから取得したデータ表示省略====== ======結果セットを破棄し、MySQLとの接続を解除省略====== ?>エラー:Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in c:\program files\... 何でこんなエラーがでるでしょう?解決方法教えてください。お願いします。

    • 締切済み
    • PHP
  • PHPから別のMySQLサーバへの接続について

    こんばんわ。 以前タイトルで質問が載っていましたが、 http://okwave.jp/qa1288968.html 根本的なところが分からない為、質問させてください。 Linux(Red Hat)にApche+PHPを入れて、別にあるMySQLサーバに 接続したいのですが、双方インストールまではできたのですが、 その後、どういうふうにやればいいのかが調べても理解できません。 まず、気になったので、PHPインストール時に--with-mysql=/usr/local/mysqlを入れてしまうとmakefileを外してしまいました。 それは問題ないでしょうか?? 自分が思っていることとして、 <mysql側> mysqladminで新規にユーザを追加。 <Apache+PHP側> .phpで接続できているかの確認 mysql_connect("192.168.0.1","サーバーで発行されたユーザ名","サーバーで発行されたパスワード"); 上記以外に何かやることはあるのでしょうか?? すいませんが、情報をお願いします。

    • 締切済み
    • PHP
  • Glassfishからmysqlへの接続

    こんにちは、ちょっと行き詰まってしまい、ご質問させて下さい。 学習用の環境としてGlassfishからmysqlへのコネクションをはろうとしています。 glassfishのバージョンは4になります。 試みたこととして ・mysql-connector-java-5.1.37-bin.jar をDLし、glassfish/lib配下に格納 ・同パスをネイティブ・ライブラリ・パスの接尾辞: に指定 ・JDBC接続プールより、『新規JDBC接続プール(ステップ1/2)』を起動。 ・リソースタイプはjavax.sql.DataSourceに指定し、データベースドライバベンダーはMySqlに指定 そのまま次へを実行すると、500エラーになってしまいます。 HTTPステータス500 - Internal Server Error type 例外レポート メッセージInternal Server Error 説明サーバーはリクエストの実行を妨げる内部エラー({0})を検出しました。 例外 java.lang.IllegalStateException: getOutputStream() has already been called for this response 色々と自分なりに調べてみたのですが、行き詰まってしまいました・・・。 ヒントだけでもいただければ助かります。 以上、よろしくお願いします。

専門家に質問してみよう