Maison  >  Article  >  Java  >  La solution Spring pour basculer dynamiquement plusieurs sources de données

La solution Spring pour basculer dynamiquement plusieurs sources de données

高洛峰
高洛峰original
2017-01-24 10:44:201704parcourir

Avant-propos

Spring configure dynamiquement plusieurs sources de données, c'est-à-dire en divisant les données en grandes applications et en utilisant plusieurs instances de base de données pour la gestion, ce qui peut améliorer efficacement l'évolutivité horizontale du système. Une telle solution sera différente de la solution commune d'instance de données unique, qui nécessite que le programme décide dynamiquement dans quelle instance de base de données stocker les données et de quelle base de données extraire les données pendant l'exécution en fonction de la demande actuelle et de l'état du système.

Spring 2.x et les versions ultérieures adoptent le mode Proxy, ce qui signifie que nous implémentons une source de données virtuelle dans la solution et l'utilisons pour encapsuler la logique de sélection de la source de données, afin que la logique de sélection de la source de données puisse être efficacement transféré de séparé du Client. Le Client fournit le contexte requis pour la sélection (car c'est ce que le Client sait) et le DataSource virtuel implémente la sélection de la source de données en fonction du contexte fourni par le Client.

Implémentation

L'implémentation spécifique est que le DataSource virtuel n'a besoin que d'hériter de AbstractRoutingDataSource pour implémenter détermineCurrentLookupKey() dans lequel la logique de sélection de la source de données est encapsulée.

1. Configurer dynamiquement plusieurs sources de données

1. Classe constante de nom de source de données :

/**
 * 动态配置多数据源
 * 数据源的名称常量类
 * @author LONGHUI_LUO
 *
 */
public class DataSourceConst {
 public static final String TEST="test";
 public static final String USER="User";
}


2. Créez une classe pour obtenir et définir l'environnement de contexte, principalement responsable de la modification du nom de la source de données contextuelles :

/**
 * 获得和设置上下文环境 主要负责改变上下文数据源的名称
 *
 * @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();
 }
  
}


3. Créez une classe de source de données dynamique. Notez que cette classe doit hériter de AbstractRoutingDataSource et implémenter la méthode détermineCurrentLookupKey. Cette méthode renvoie un objet, généralement une chaîne :

/**
 * 建立动态数据源
 *
 * @author LONGHUI_LUO
 *
 */
public class DynamicDataSource extends AbstractRoutingDataSource {
  
 protected Object determineCurrentLookupKey() {
 // 在进行DAO操作前,通过上下文环境变量,获得数据源的类型
 return DataSourceContextHolder.getDataSourceType();
 }
  
}

.


4. Écrivez les fichiers de configuration Spring pour configurer plusieurs sources de données

  <!-- 数据源相同的内容 -->
<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 配置各个数据源的特性 -->


5. Le fichier de configuration spring configure plusieurs relations de mappage de sources de données

<bean class="com.xxxx.datasouce.DynamicDataSource" id="dataSource">
 <property name="targetDataSources">
  <map key-type="java.lang.String">
   <entry value-ref="testDataSource" key="test"></entry>
   <entry value-ref="UserDataSource" key="User"></entry>
  </map>
 </property>
 <property name="defaultTargetDataSource" ref="testDataSource" ></property>
</bean>


Dans cette configuration, le premier attribut de propriété configure la source de données cible, 87572c48d11529cf3c8a243cd9742b3d doit être le même que le type de valeur dans la classe de comparaison clé-valeur statique DataSourceConst;fd9cd61ce1e9b7852bdf43dba8b7c44b. Le deuxième attribut de propriété configure la source de données par défaut.

La commutation dynamique est la source de données

DataSourceContextHolder.setDataSourceType(DataSourceConst.TEST);


Les avantages de cette solution

Tout d'abord , cette solution est complètement résolue sous le framework Spring. La source de données est toujours configurée dans le fichier de configuration Spring et la sessionFactory configure toujours son attribut dataSource. Elle ne connaît même pas le changement de dataSource. La seule différence est qu'un MultiDataSource est ajouté entre le vrai dataSource et sessionFactory.

Deuxièmement, il est simple à mettre en œuvre et facile à entretenir. Bien que j'aie tant dit sur ce plan, il ne s'agit en fait que d'analyses. Le seul code que nous avons réellement besoin d'écrire est MultiDataSource et SpObserver. Les deux seules méthodes qui doivent réellement être écrites dans la classe MultiDataSource sont getDataSource() et getDataSource(sp), tandis que la classe SpObserver est encore plus simple. Plus la mise en œuvre est simple, plus le risque d’erreurs est faible et plus la maintenabilité est élevée.

Enfin, cette solution peut rendre une source de données unique compatible avec plusieurs sources de données. Cette solution n'affecte pas du tout l'écriture de BUS et DAO. Si notre projet est développé avec une seule source de données au début et doit être remplacé par plusieurs sources de données au fur et à mesure de l'avancement du projet, il nous suffit de modifier la configuration Spring et une petite quantité de modifications à la couche MVC pour écrire les données requises. dans la demande Nom de la source de données, la modification est terminée. Si notre projet souhaite revenir à une source de données unique, il suffit de modifier simplement le fichier de configuration. Cela ajoutera plus de flexibilité à notre projet.

Inconvénients de cette solution

Elle ne résout pas le problème du partage de la variable "dataSource" lorsque plusieurs utilisateurs accèdent au singleton "sessionFactory", ce qui entraîne un résultat de conflit pour " dataSource", qui est essentiellement similaire au problème "producteur-consommateur" dans les systèmes d'exploitation. Par conséquent, lorsque plusieurs utilisateurs y accèdent, plusieurs sources de données peuvent entraîner une dégradation des performances du système.

Résumé

Ce qui précède est l'intégralité du contenu de cet article. J'espère que le contenu de cet article pourra être utile aux études ou au travail de chacun. Si vous avez des questions, vous pouvez partir. un message à communiquer.

Pour plus d'articles liés à la solution Spring permettant de basculer dynamiquement plusieurs sources de données, veuillez faire attention au site Web PHP chinois !

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn