MyBatisの複数のデータソースは、ピット、データベース接続が頻繁に切断されている問題を強化しました

問題

最近のプロジェクトの奇妙な質問は、データベースは、多くの場合、数時間ごとに、それは、接続が閉じられたと報告しました

次のような構成であってもほかにもまだ動作しませんが、インターネットはピットを説明する任意の記事を見つけることができませんでした

test-on-borrow: true
test-while-idle: true
validation-query: select 1 from dual
复制代码

なぜ3件の記事を見ることができ、接続が中断された設定に上記を解決することができます

調査

オンラインでは、唯一の自分の精査の推測をすることができます見つけます。それはMyBatisの複数のデータソースを設定しているため、各DBの設定は、Iは、具体的な接続構成として書かれています。

私は、データソースを作成するデフォルトの方法を使用しませんので、私はapplication.yml設定を書き込むことが読んでいないので、DataSourceConfigコードを見て、私は突然、考えました:

    @Bean(name = "db1DataSource")
    @ConfigurationProperties(prefix = "spring.datasource.db1")
    @Primary
    public DataSource dbDataSource() {
        return DataSourceBuilder.create().build();
    }
复制代码

決定的なフォローアップのビルド()メソッド

	public DataSource build() {
		Class<? extends DataSource> type = getType();
		DataSource result = BeanUtils.instantiate(type);
		maybeGetDriverClassName();
		bind(result);
		return result;
	}
复制代码

返された結果を見ることができます。この時点でブレークポイントを作成し、新しいデータソースであります

だから我々はdbDataSourceは()メソッドを変更することができ、我々は、設定パラメータを記述します。

 @Value("${spring.datasource.db1.url}")
    private String url;
    @Value("${spring.datasource.db1.username}")
    private String username;
    @Value("${spring.datasource.db1.password}")
    private String password;
    @Value("${spring.datasource.db1.tomcat.test-on-borrow}")
    private boolean testOnBorrow;
    @Value("${spring.datasource.db1.tomcat.test-while-idle}")
    private boolean testWhileIdle;
    @Value("${spring.datasource.db1.tomcat.validation-query}")
    private String validationQuery;
    @Value("${spring.datasource.db1.tomcat.max-idle}")
    private int maxIdle;
    @Value("${spring.datasource.db1.tomcat.min-idle}")
    private int minIdle;
    @Value("${spring.datasource.db1.tomcat.initial-size}")
    private int initialSize;
    @Value("${spring.datasource.db1.tomcat.max-active}")
    private int maxActive;
    @Value("${spring.datasource.db1.tomcat.time-between-eviction-runs-millis}")
    private int timeBetweenEvictionRunsMillis;

    @Bean(name = "db1DataSource")
    @ConfigurationProperties(prefix = "spring.datasource.db1")
    @Primary
    public DataSource dbDataSource() {
        org.apache.tomcat.jdbc.pool.DataSource dataSource = new org.apache.tomcat.jdbc.pool.DataSource();
        dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver");
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setMaxActive(maxActive);
        dataSource.setMinIdle(minIdle);
        dataSource.setMaxIdle(maxIdle);
        dataSource.setTestOnBorrow(testOnBorrow);
        dataSource.setTestWhileIdle(testWhileIdle);
        dataSource.setValidationQuery(validationQuery);
        dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
        dataSource.setInitialSize(initialSize);
        return dataSource;
        //return DataSourceBuilder.create().build();
    }
复制代码

二次調査

あなたは本当に上記の方法で問題を解決することができますが、私は突然、デフォルトで作成されたDataSourceが必要な基本的な情報のURL、ユーザ名、パスワードなどではない、と思いました だからこそ、これらの設定パラメータだとそれに書き込むことができますか?

私たちはdbDataSourceメソッドを持っている参照してください。この時間は@Bean(name = "db1DataSource")、我々はこれらの設定パラメータを注入ので、大胆な推測では、SpringのIOC注入により作成された最初の時間です。私によってデバッグはそれがあるという事実を発見しました。

メソッドのDataBinderブレークポイントバインドクラス、

	public void bind(PropertyValues pvs) {
		MutablePropertyValues mpvs = (pvs instanceof MutablePropertyValues) ?
				(MutablePropertyValues) pvs : new MutablePropertyValues(pvs);
		doBind(mpvs);
	}
复制代码

私たちは、呼び出しパス方法を見ることができます

おなじみのリフレッシュ大法、ソースコードに関連するルック春のこの部分を参照してください。春のソースコード解析を

この時だけは間違い、私達のURL、ユーザ名、パスワードなどを最後DataSourceがIOCから内部に注入するので、他の引数なぜ?父親のクラスインタフェースPoolConfigurationを見つけるために、すべての道までの私のDataSourceクラスを使用すると、すべてのパラメータとGETSET方法を参照してください。

私application.ymlコンフィギュレーションファイルのパラメータを見てください

spring:
    datasource:
        db1:
            url: 
            username: 
            password: 
            driver-class-name: oracle.jdbc.driver.OracleDriver
            tomcat:
                max-wait: 10000
                max-active: 30
                test-on-borrow: true
                max-idle: 5
        db2:
            xxx
            ....
复制代码

最後に、この1つのアップを発見!
パラメータ設定がされている春のデータ元のデフォルトのtomcat-JDBC接続プール

spring:
    datasource:
        url: 
        username: 
        password: 
        driver-class-name: oracle.jdbc.driver.OracleDriver
        tomcat:
            max-wait: 10000
            max-active: 30
            test-on-borrow: true
            max-idle: 5
复制代码

マルチデータソース構成とシンプルを使用している場合は、あなただけの過去をコピーすることができ、そのウェイトをtomcat.maxために読んだときIOC春の注入は、setMaxWait方法でDataSourceを一致していません。自然は動作しません。

次のようにこの問題は、読み取り専用にファイルを設定する必要があります

spring:
    datasource:
        db1:
            url: 
            username: 
            password: 
            driver-class-name: oracle.jdbc.driver.OracleDriver
            max-wait: 10000
            max-active: 30
            test-on-borrow: true
            test-while-idle: true
            validation-query: select 1 from dual
            max-idle: 5
        db2:
            xxx
            ....
复制代码

概要

結果からの問題は、それは簡単ではありませんが、プロセスから、私は再びその上に手放すと、スプリングIOCプロセス、私はステップの切開によって、この問題のステップを感じさせ、より多くの知識のドットを接続するだけでなく、達成感。あなたは春のソースまで学習していない場合は、高い確率で私はそれは豆の注入を見ることだと思いません

おすすめ

転載: juejin.im/post/5d673fbc5188256e8b5d0490