- PR -

DBCPのDBセッションについて

投稿者投稿内容
タマ
ベテラン
会議室デビュー日: 2004/08/08
投稿数: 56
投稿日時: 2004-10-24 10:41
おかもとさん>
 ありがとうございます。
 使用しているサーバはTOMCATです。

kitoさん>
 ありがとうございます。
 KITOさんの方法のほうが簡単そうですね。
 やってみます。
 DataSource dataSource = (DataSource)new InitialContext().lookup ("java:comp/env/jdbc/sampledb");


 を行うことで、
 私 みたくセッションを受け渡ししなくても
 サーバ側で保持してるプーリングを使用できる
 と解釈したのですがよろしいでしょうか??



お二方の言っていられるのは↓のことですよね?
http://www.hellohiro.com/datasource.htm

私が参考にしたのはここですが、私の解釈違いでしょうか?
http://www.atmarkit.co.jp/fjava/rensai2/jakarta06/jakarta06.html

はしもと
大ベテラン
会議室デビュー日: 2003/02/05
投稿数: 182
投稿日時: 2004-10-24 12:31
引用:
タマさんの書き込み (2004-10-23 21:55) より:
お手数ですが、具体的にどのようにソースを変更したらよいか
教えていただけないでしょうか?



方法はいろいろありますが、一例を書きます。

ServletContext に登録されたオブジェクトは、そのウェブアプリが
unload されるか removeAttribute() するまで消えませんから、
常に 1 つの DBCP の提供するプールから Connection を取得
します。

下はあくまでも例であって、実際に動かすと問題がおきます。

コード:

// ServletContext から DataSource を取得
DataSource dataSource = (DataSource) getServletContext().getAttribute("dataSource");

// DataSource が登録されてなかったら作る
if (dataSource == null) {
Class.forName(str_drv);
// ObjectPoolインスタンスを生成
ObjectPool pool = new StackObjectPool();

// Connectionオブジェクトを生成するためのConnectionFactoryインスタンスを生成
ConnectionFactory cn_factory = new DriverManagerConnectionFactory(str_dsn, str_user, str_pass);

// PoolableConnectionFactoryインスタンスを生成
// 第6引数:true →プールから取り出されたConnectionを自動コミットモードにする
//      false→プールから取り出されたConnectionを自動コミットモードにしない
new PoolableConnectionFactory(
cn_factory
,pool
,null
,null
,false
,true
);

// プーリング機能を持つDataSourceインスタンスを生成
PoolingDataSource sop = new PoolingDataSource(pool);

dataSource = sop;

// DataSource を ServletContext に登録
getServletContext().setAttribute("dataSource", sop);
}

// DataSource から Connection を取得
Connection conn = dataSource.getConnection();

// 以下略




[ メッセージ編集済み 編集者: はしもと 編集日時 2004-10-24 12:34 ]
おかもと
大ベテラン
会議室デビュー日: 2003/06/08
投稿数: 182
投稿日時: 2004-10-24 14:42
引用:

タマさんの書き込み (2004-10-24 10:41) より:
 DataSource dataSource = (DataSource)new InitialContext().lookup ("java:comp/env/jdbc/sampledb");


 を行うことで、
 私 みたくセッションを受け渡ししなくても
 サーバ側で保持してるプーリングを使用できる
 と解釈したのですがよろしいでしょうか??




そうです。後は、毎回ルックアップするのをロスと感じるなら
DataSrouceをServletContextに保持するなどの対策を採ります。
私が検証した限りではルックアップにかかるコストは微々たる物ですし、
Tomcatの場合1回目より2回目以降のルックアップ速度が劇的に
速くなっている事から、毎回ルックアップしております。(今のところ)

引用:


私が参考にしたのはここですが、私の解釈違いでしょうか?
http://www.atmarkit.co.jp/fjava/rensai2/jakarta06/jakarta06.html




Commons-PoolやCommons-DBCPの説明となると上記例のようになるのでしょう。
アプリケーションサーバーの機能を使ってしまうとDBCPの解説としては
不十分になってしまいますから。
タマ
ベテラン
会議室デビュー日: 2004/08/08
投稿数: 56
投稿日時: 2004-10-25 21:37
言われたとおりにしてみたのですが以下のようなエラーがでてしまいました。

どう対処したらよいでしょう。
いろいろ試してみたのですがエラーが消えません。

org.apache.commons.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null', cause:

=接続部分=
public void doGet(HttpServletRequest request, HttpServletResponse response){

Connection obj_cn = null; // Line情報格納ハッシュ

DataSource dataSource = (DataSource)new InitialContext().lookup("java:comp/env/jdbc/Oracle");
obj_cn = dataSource.getConnection();
}


=====conf/server.xml=====
<Context ・・・/>
<Resource name="jdbc/Oracle" auth="Container" type="javax.sql.DataSource"/>
<ResourceParams name="jdbc/Oracle">
<parameter>
<name>username</name>
<value>・・・</value>
</parameter>

<parameter>
<name>password</name>
<value>・・・</value>
</parameter>

<parameter>
<name>driverClassName</name>
<value>oracle.jdbc.driver.OracleDriver</value>
</parameter>

<parameter>
<name>URL</name>
<value>jdbc:oracle:thin:@ip:port:sid</value>
</parameter>

<parameter>
<name>maxActive</name>
<value>10</value>
</parameter>

<parameter>
<name>maxIdle</name>
<value>5</value>
</parameter>

<parameter>
<name>maxWait</name>
<value>10000</value>
</parameter>

<parameter>
<name>removeAbandoned</name>
<value>true</value>
</parameter>

<parameter>
<name>removeAbandonedTimeout</name>
<value>300</value>
</parameter>

</ResourceParams>

<Realm
className="org.apache.catalina.realm.JDBCRealm" debug="0"
driverName="oracle.jdbc.driver.OracleDriver"
connectionURL="・・・"
connectionName="・・・"
connectionPassword="・・・"
userTable="LOGIN_・・・_"
userNameCol="・・・_・・・"
userCredCol="・・・_・・・"
userRoleTable="・・・_・・・_"
roleNameCol="・・・_・・・"
/>


=====web-inf/web.xml=====
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>

<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/Oracle</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>

<security-constraint>
<web-resource-collection>
<web-resource-name>Authentication of FormAuth</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>・・・</role-name>
</auth-constraint>
</security-constraint>

<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/Login.jsp</form-login-page>
<form-error-page>/login_err.html</form-error-page>
</form-login-config>
</login-config>

</web-app>

kito
ベテラン
会議室デビュー日: 2003/03/24
投稿数: 59
お住まい・勤務地: Osaka
投稿日時: 2004-10-25 22:31
引用:

タマさんの書き込み (2004-10-25 21:37) より:
言われたとおりにしてみたのですが以下のようなエラーがでてしまいました。

org.apache.commons.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null', cause:
コード:
    <parameter>
      <name>URL</name>
      <value>jdbc:oracle:thin:@ip:port:sid</value>
    </parameter>




パラメータ名はURLではなくて、urlです。

それから、(特定の環境では差は無いかもしれませんが、)
キャッシュすべきものはやはりキャッシュした方が良いと思いますよ。
環境によってはJNDIのlookup()にとても時間がかかるかもしれませんから。
dataSouceはServletのメンバにしてServlet#init()で取得してしまいましょう。
タマ
ベテラン
会議室デビュー日: 2004/08/08
投稿数: 56
投稿日時: 2004-10-25 22:54
キャッシュの件ご指摘いただきありがとうございます。

変更します!!

URLの件ですがurlと書いたのですがだめだったので、URLにして試したのですが
そのまま投稿してしまったみたいです。

どちらでもだめでした。
おかもと
大ベテラン
会議室デビュー日: 2003/06/08
投稿数: 182
投稿日時: 2004-10-26 00:12
たしかにキャッシュに関しては念のため行っても無駄にはなりませんね。
ただ、JNDIで取得したリソースをキャッシュするような手法は
EJB以外では見たこと無いですね。BBSなどの意見としては見かけますが。

さて、エラーの件ですが、JDBCドライバはTomcatのクラスローダーが
読める場所に置いてますか?
kito
ベテラン
会議室デビュー日: 2003/03/24
投稿数: 59
お住まい・勤務地: Osaka
投稿日時: 2004-10-26 00:33
引用:

タマさんの書き込み (2004-10-25 22:54) より:
URLの件ですがurlと書いたのですがだめだったので、URLにして試したのですが
そのまま投稿してしまったみたいです。

どちらでもだめでした。


おそらくその時々でエラーメッセージが変わっていると思います。
エラーメッセージに沿って設定を修正しましょう。

引用:

おかもとさんの書き込み (2004-10-26 00:12) より:
たしかにキャッシュに関しては念のため行っても無駄にはなりませんね。
ただ、JNDIで取得したリソースをキャッシュするような手法は
EJB以外では見たこと無いですね。BBSなどの意見としては見かけますが。


う〜んそれはよほど特殊な環境のような・・・
EJBHomeをキャッシュしてDataSourceをキャッシュしない理由が私にはわかりません。

スキルアップ/キャリアアップ(JOB@IT)