代码之家  ›  专栏  ›  技术社区  ›  We are Borg

Java,Spring:创建一个单独的数据源bean

  •  0
  • We are Borg  · 技术社区  · 7 年前

    我正在开发一个Spring MVC应用程序,到目前为止,我们只有一个数据源。对于我们的需求,大多数事务都是短期的,我们确实有一些应用程序很少需要很长时间来处理。为了避免系统因这些请求而阻塞,我们计划创建一个单独的数据源。

    除此之外,这些方法的优先级较低,因为用户知道这些方法需要更长的时间。为此,我只是打电话 Thread.currentThread().setPriority(Thread.MIN_PRIORITY); .这够了吗?主要的一点是,这些方法不应该在CPU、磁盘、I/O等方面消耗更多的时间。

    与其他spring mvc应用程序一样,我们有3层,控制器、服务和DAO。一些服务层方法将在这些数据源之间共享。例子: long_method_service_layer()-->dependent_method_service_layer() 而且 short_method_service_layer()-->dependent_method_service_layer();

    那么,当第二个数据源调用dependent_method()时,它的优先级是否也较低?

    目前,我们的服务层配置如下:

    @Service
    @Transactional
    public class DownloadTokenServiceImpl implements DownloadTokenService{
    
        private final DownloadTokenDAO downloadTokenDAO;
    
        @Autowired
        public DownloadTokenServiceImpl(DownloadTokenDAO downloadTokenDAO){
            this.downloadTokenDAO = downloadTokenDAO;
        }
    
    @Override
    public void method_name(){}
    }
    

    来自第二个数据源的方法也将在这个类中。我计划用 @Transactional("2nd_source") .对吗?

    最后,我现在尝试的错误日志:

    Caused by: 
    org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.hibernate.SessionFactory] is defined: expected single matching bean but found 2: hibernate4AnnotatedSessionFactory_extended,hibernate4AnnotatedSessionFactory
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1133)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1021)
        at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:814)
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
        at org.s
    

    根上下文。xml:

    第一个数据源(主要):

    <beans:bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"  destroy-method="close">
            <beans:property name="dataSourceClassName" value="org.postgresql.ds.PGSimpleDataSource"/>
           <beans:property name="maximumPoolSize" value="50" />
            <beans:property name="maxLifetime" value="200000" />
            <beans:property name="idleTimeout" value="25000" />
            <beans:property name="leakDetectionThreshold" value="200000"/>
            <beans:property name="connectionTimeout" value="200000"/>
            <beans:property name="dataSourceProperties">
                <beans:props>
                    <beans:prop key="url">jdbc:postgresql://localhost:5432/DB_NAME</beans:prop>
                    <beans:prop key="user">username</beans:prop>
                    <beans:prop key="password">password</beans:prop>
                </beans:props>
            </beans:property>
        </beans:bean>
    
        <!-- Hibernate 4 SessionFactory Bean definition -->
        <beans:bean id="hibernate4AnnotatedSessionFactory"
                    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
            <beans:property name="dataSource" ref="dataSource"/>
            <beans:property name="packagesToScan" value="com.our_app.spring.model"/>
            <beans:property name="hibernateProperties">
                <beans:props>
                    <beans:prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQL9Dialect</beans:prop>
                    <beans:prop key="hibernate.show_sql">false</beans:prop>
                    <beans:prop key="hibernate.jdbc.batch_size">50</beans:prop>
                    <beans:prop key="hibernate.hbm2ddl.auto">update</beans:prop>
                    <beans:prop key="cache.use_second_level_cache">true</beans:prop>
                    <beans:prop key="cache.use_query_cache">true</beans:prop>
                    <beans:prop key="hibernate.order_updates">true</beans:prop>
                    <beans:prop key="show_sql">false</beans:prop>
                    <beans:prop key="connection.release_mode">after_statement</beans:prop>
                </beans:props>
            </beans:property>
        </beans:bean>
    
    
        <tx:annotation-driven transaction-manager="transactionManager"/>
    
        <beans:bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
            <beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
        </beans:bean>
    

    第二个数据源(对于长时间运行的事务来说是必需的,hikari值在其工作后进行调整):

     <beans:bean id="extended_transactions_data_source" class="com.zaxxer.hikari.HikariDataSource"  destroy-method="close">
            <beans:property name="dataSourceClassName" value="org.postgresql.ds.PGSimpleDataSource"/>
            <beans:property name="maximumPoolSize" value="50" />
            <beans:property name="maxLifetime" value="200000" />
            <beans:property name="idleTimeout" value="25000" />
            <beans:property name="leakDetectionThreshold" value="200000"/>
            <beans:property name="connectionTimeout" value="200000"/>
            <beans:property name="dataSourceProperties">
                <beans:props>
                    <beans:prop key="url">jdbc:postgresql://localhost:5432/Db_NAME</beans:prop>
                    <beans:prop key="user">USERNAME</beans:prop>
                    <beans:prop key="password">passwoRD</beans:prop>
                </beans:props>
            </beans:property>
        </beans:bean>
    
    
        <!-- Hibernate 4 SessionFactory Bean definition -->
        <beans:bean id="hibernate4AnnotatedSessionFactory_extended"
                    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
            <beans:property name="dataSource" ref="extended_transactions_data_source"/>
            <beans:property name="packagesToScan" value="com.our_app.spring.model"/>
            <beans:property name="hibernateProperties">
                <beans:props>
                    <beans:prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQL9Dialect</beans:prop>
                    <beans:prop key="hibernate.show_sql">false</beans:prop>
                    <beans:prop key="hibernate.jdbc.batch_size">50</beans:prop>
                    <beans:prop key="hibernate.hbm2ddl.auto">update</beans:prop>
                    <beans:prop key="cache.use_second_level_cache">true</beans:prop>
                    <beans:prop key="cache.use_query_cache">true</beans:prop>
                    <beans:prop key="hibernate.order_updates">true</beans:prop>
                    <beans:prop key="show_sql">false</beans:prop>
                    <beans:prop key="connection.release_mode">after_statement</beans:prop>
                </beans:props>
            </beans:property>
        </beans:bean>
    
           <tx:annotation-driven transaction-manager="transactionManager_extended"/>
    
        <beans:bean id="transactionManager_extended" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
            <beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory_extended"/>
        </beans:bean>
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Michael Peacock    7 年前

    我不认为这是一个精确的复制品 this post ,但它有很多相似之处。看一下这里接受的答案,注意在DAO中,它们自动连接两个会话工厂。作者还使用限定符注释来保持独立。在DAO中,您可能需要执行以下操作:

      @Autowired
      @Qualifier(value="hibernate4AnnotatedSessionFactory")
      private SessionFactory hibernate4AnnotatedSessionFactory;
    
      @Autowired
      @Qualifier(value="hibernate4AnnotatedSessionFactory_extended")
      private SessionFactory hibernate4AnnotatedSessionFactory_extended;
    

    认为 在这种情况下,您不必限定事务性注释,因为DAO实现必须显式使用一个或另一个会话工厂。