HikariCPへの対応依頼

482 views
Skip to first unread message

taktos

unread,
May 9, 2018, 1:39:17 AM5/9/18
to DBFluteユーザの集い
ご無沙汰してます、たきぐちです。

SpringBoot 2.0から、デフォルトのコネクションプールがTomcatからHikariCP (https://github.com/brettwooldridge/HikariCP) に変更されました。
この関係で、SpringBoot 2.0とDBFluteを一緒に使った場合、トランザクション管理が行われなくなってしまっています。

DBFluteInitializer#needsSpringTransactionalDataSource メソッドを以下のような感じで修正すればHikariCPでも正常に動きましたので、可能でしたら対応いただけますと幸いです。
# ついでにDBCP 2 (org.apache.commons.dbcp2) も追加しておくと安心かも

protected boolean needsSpringTransactionalDataSource(String dataSourceFqcn) {
    return dataSourceFqcn.startsWith("org.apache.commons.dbcp.")
        || dataSourceFqcn.startsWith("org.apache.commons.dbcp2.")
        || dataSourceFqcn.startsWith("org.apache.tomcat.jdbc.pool.")
        || dataSourceFqcn.startsWith("com.zaxxer.hikari.");
}

kubo

unread,
May 9, 2018, 1:44:05 AM5/9/18
to DBFluteユーザの集い
jfluteです

たきぐちさん、こんにちは

> DBFluteInitializer#needsSpringTransactionalDataSource メソッドを以下のような感じで修正すればHikariCPでも正常に動きましたので、可能でしたら対応いただけますと幸いです。
> # ついでにDBCP 2 (org.apache.commons.dbcp2) も追加しておくと安心かも

おおぉ、貴重なフィードバックありがとうです。
後で対応しておきます。

kubo

unread,
May 9, 2018, 7:58:09 AM5/9/18
to DBFluteユーザの集い
jfluteです

たきぐちさん

対応して、DBFlute-1.1.7 のパッチとしてアップしました!
ありがとうございます。

protected boolean needsSpringTransactionalDataSource(String
dataSourceFqcn) {
return dataSourceFqcn.startsWith("org.apache.commons.dbcp.")
|| dataSourceFqcn.startsWith("org.apache.commons.dbcp2.")
|| dataSourceFqcn.startsWith("org.apache.tomcat.jdbc.pool.")
|| dataSourceFqcn.startsWith("com.zaxxer.hikari.");
}

すでに 1.1.7 の場合は、DBFluteエンジン (mydbflute) だけ、
ダウンロードして取り替えてください。
それよりも古いバージョンの場合は、1.1.7にアップグレードをお願いします。

takiguchi

unread,
May 17, 2018, 2:55:16 AM5/17/18
to dbf...@googlegroups.com
jfluteさん

遅くなってすみません。
mydbflute下のdbflute-1.1.7を削除してダウンロードし直して、
改善されていることを確認しました。
ご対応ありがとうございました!!!

--
Toshio Takiguchi


2018年5月9日 20:57 kubo <dbf...@gmail.com>:
> --
> このメールは Google グループのグループ「DBFluteユーザの集い」の登録者に送られています。
> このグループから退会し、グループからのメールの配信を停止するには dbflute+u...@googlegroups.com にメールを送信してください。
> このグループに投稿するには、dbf...@googlegroups.com にメールを送信してください。
> https://groups.google.com/group/dbflute からこのグループにアクセスしてください。
> その他のオプションについては、https://groups.google.com/d/optout にアクセスしてください。

kubo

unread,
May 17, 2018, 5:30:21 AM5/17/18
to DBFluteユーザの集い
jfluteです

たきぐちさん、
確認ありがとうです!良かった。

そろそろ 1.1.8 も出します。

Y Watanabe

unread,
May 18, 2018, 12:09:22 AM5/18/18
to DBFluteユーザの集い
渡辺です。

 protected boolean needsSpringTransactionalDataSource(String 
dataSourceFqcn) { 
        return dataSourceFqcn.startsWith("org.apache.commons.dbcp.") 
            || dataSourceFqcn.startsWith("org.apache.commons.dbcp2.") 
            || dataSourceFqcn.startsWith("org.apache.tomcat.jdbc.pool.") 
            || dataSourceFqcn.startsWith("com.zaxxer.hikari."); 
    } 

のような調子であらゆるDBコネクションプールライブラリに対応してゆくのもきつい気がするので、

@Bean
public javax.sql.DataSource dataSource() {

        HikariConfig config = new HikariConfig();

        config.setDriverClassName(props.getDriverClassName());
        config.setJdbcUrl(props.getUrl());
        config.setUsername(props.getUsername());
        config.setPassword(props.getPassword());
        // その他の細かい設定もろもろ

        HikariDataSource ds = new HikariDataSource(config);

        // springのトランザクション管理機構で包み込む。
        // これをやらないと@Transactionalでのトランザクション管理がおかしくなる
        return new TransactionAwareDataSourceProxy(ds);
    }

こういうふうに明示的に TransactionAwareDataSourceProxy を使うようにマニュアル上で呼びかけるとかどうでしょう。

#もしできたらほんとうにこれで DBFlute1.1.6 + HikariCP + Spring  でトランザクション管理がされるかどうか
#検証していただけると大っっ変助かったりするのですが^^;)


あるいは

if (dataSource instanceof TransactionAwareDataSourceProxy) {
  // springに任せられるので何もしない
} else {
  // DBFlute(が自動生成したDBInitializer.java)自身がそれをやってしまう!?
  dataSource = new TransactionAwareDataSourceProxy(dataSource)
}

みたいなふうにした方が将来的にわたってあんしんできるような気がします。

kubo

unread,
May 18, 2018, 3:35:19 AM5/18/18
to DBFluteユーザの集い
jfluteです

nabedgeさん、ありがとうございます。

> こういうふうに明示的に TransactionAwareDataSourceProxy を使うようにマニュアル上で呼びかけるとかどうでしょう。

明示的に指定ができるようにするのは良いですね。

ただ、すでに現状で、
「認識しているConnectionPoolであれば自動で動く」
ようになっているのを、
マイナーバージョンアップでやるのは厳しいので、
どのみち needsSpringTransactionalDataSource() はしばらくは
残さざるを得ないです。
(そもそも自動でTransactionが効かせたいというのもあり)

一方で、すでに DBFluteConfig で DataSourceHandler で、
明示的に設定をすることができます。
(一応、ドキュメントにも書いてあります。が、ちょと古いですね...直します)
http://dbflute.seasar.org/ja/manual/reference/diway/spring/index.html#commonsdbcp
ただ、TransactionAwareDataSourceProxy とインターフェースの相性が悪いので、
もうちょいやりやすいようにはしたいですね。

> // DBFlute(が自動生成したDBInitializer.java)自身がそれをやってしまう!?
> dataSource = new TransactionAwareDataSourceProxy(dataSource)
どのConnectionPoolライブラリであろうが、
Springであれば問答無用でTransactionAwareDataSourceProxyで
ラップしてしまっていいのでしょうか?
(であれば、もうそうしちゃってもいいのかも!?)

kubo

unread,
May 18, 2018, 11:33:22 AM5/18/18
to DBFluteユーザの集い
jfluteです

> (一応、ドキュメントにも書いてあります。が、ちょと古いですね...直します)
> http://dbflute.seasar.org/ja/manual/reference/diway/spring/index.html#commonsdbcp

色々と内容が古かったので刷新しました。

// Spring Frameworkの取扱い | DBFlute
http://dbflute.seasar.org/ja/manual/reference/diway/spring/index.html


> if (dataSource instanceof TransactionAwareDataSourceProxy) {
> // springに任せられるので何もしない
> } else {
> // DBFlute(が自動生成したDBInitializer.java)自身がそれをやってしまう!?
> dataSource = new TransactionAwareDataSourceProxy(dataSource)
> }

もうちょいTransactionAwareDataSourceProxyのコードを読んで、
デフォルトで組み込めるようであれば組み込みたいですね。

TransactionAwareDataSourceProxyでラップすると逆に困る人がいないかどうか、
そこが心配なのでもう少し見極めたいところです。
(例えば、すでにスレッドトランザクションをサポートしているDataSourceで
ラップしていた場合、二重になって変なことにならないか、とか)


# ちなみに、TransactionAwareDataSourceProxyのコード、ちょこっと読むと...
# java.lang.reflect.Proxy を使っててなんだか懐かしい(^^
Reply all
Reply to author
Forward
0 new messages