はじめに
Spring は複数のデータ ソースを動的に構成します。つまり、大規模なアプリケーションでデータをセグメント化し、管理に複数のデータベース インスタンスを使用することで、システムの水平方向のスケーラビリティを効果的に向上させることができます。このようなソリューションは、現在のリクエストとシステム ステータスに基づいて、実行時にどのデータベース インスタンスにデータを保存するか、どのデータベースからデータを抽出するかをプログラムが動的に決定する必要がある、一般的な単一データ インスタンス ソリューションとは異なります。
Spring 2.x 以降のバージョンではプロキシ モードが採用されています。つまり、ソリューションに仮想データ ソースを実装し、それを使用してデータ ソース選択ロジックをカプセル化することで、データ ソース選択ロジックをクライアントから効果的に分離できます。 。クライアントは選択に必要なコンテキストを提供し (これはクライアントが知っていることであるため)、仮想データソースはクライアントによって提供されたコンテキストに基づいてデータ ソースの選択を実装します。
実装
具体的な実装では、仮想 DataSource は、AbstractRoutingDataSource を継承して、terminateCurrentLookupKey() を実装し、データ ソースの選択ロジックをカプセル化するだけで済みます。
1. 複数のデータソースを動的に構成します
1. データソースの名前定数クラス:
2. コンテキスト環境を取得および設定するクラスを作成します。コンテキスト データ ソース :
/** * 动态配置多数据源 * 数据源的名称常量类 * @author LONGHUI_LUO * */ public class DataSourceConst { public static final String TEST="test"; public static final String USER="User"; }
3. このクラスは AbstractRoutingDataSource を継承し、メソッド detectCurrentLookupKey を実装する必要があることに注意してください。このメソッドはオブジェクト (通常は文字列) を返します。
4. 複数のデータ ソースを構成するスプリング構成ファイルを作成します
/** * 获得和设置上下文环境 主要负责改变上下文数据源的名称 * * @author LONGHUI_LUO * */ public class DataSourceContextHolder { private static final ThreadLocal contextHolder = new ThreadLocal(); // 线程本地环境 // 设置数据源类型 public static void setDataSourceType(String dataSourceType) { contextHolder.set(dataSourceType); } // 获取数据源类型 public static String getDataSourceType() { return (String) contextHolder.get(); } // 清除数据源类型 public static void clearDataSourceType() { contextHolder.remove(); } }
5. 複数のデータ ソースのマッピング関係を構成するスプリング構成ファイルを作成します
/** * 建立动态数据源 * * @author LONGHUI_LUO * */ public class DynamicDataSource extends AbstractRoutingDataSource { protected Object determineCurrentLookupKey() { // 在进行DAO操作前,通过上下文环境变量,获得数据源的类型 return DataSourceContextHolder.getDataSourceType(); } }
この構成では、最初のプロパティ属性の設定 ターゲット データ ソース。
動的切り替えはデータソースです
<!-- 数据源相同的内容 --> <bean id="parentDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" /> <property name="username" value="sa" /> <property name="password" value="net2com" /> </bean> <!-- start以下配置各个数据源的特性 --> <bean parent="parentDataSource" id="testDataSource"> <propertynamepropertyname="url" value="jdbc:sqlserver://localhost:1433;databaseName=test" /> </bean> <bean parent="parentDataSource" id="UserDataSource"> <property name="url" value="jdbc:sqlserver://localhost:1433;databaseName=User" /> </bean> <!-- end 配置各个数据源的特性 -->
このソリューションの利点
まず第一に、このソリューションは Spring フレームワークの下で完全に解決されており、データ ソースは依然として Spring 構成ファイルで構成されています。 sessionFactory はまだ dataSource プロパティが構成されており、dataSource の変更についても認識しません。唯一の違いは、MultiDataSource が実際の dataSource と sessionFactory の間に追加されることです。
2 番目に、実装が簡単で、メンテナンスも簡単です。この計画については多くのことを述べてきましたが、実際に記述する必要があるのはすべて分析です。MultiDataSource と SpObserver だけです。 MultiDataSource クラスに実際に記述する必要があるメソッドは getDataSource() と getDataSource(sp) の 2 つだけですが、SpObserver クラスはさらに単純です。実装が単純であればあるほど、エラーの可能性が小さくなり、保守性が高くなります。
複数のユーザーがシングルトンの「sessionFactory」にアクセスするときに「dataSource」変数を共有する問題を解決できず、本質的には次のような「dataSource」の競合が発生します。オペレーティング システムに関する質問の「生産者と消費者」。したがって、複数のユーザーがアクセスすると、複数のデータ ソースによってシステムのパフォーマンスが低下する可能性があります。
概要