空间站

北极心空

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  15 Posts :: 393 Stories :: 160 Comments :: 0 Trackbacks

问题的分析

我首先想到在spring但是,我很快发现一个问题:当多用户同时并发访问数据库的时候会出现资源争用的问题。这都是“单例模式”惹的祸。众所周知,我们在使用spring通过以上的分析,解决多数据源访问问题的关键,就集中在sessionFactory(一)            采用Decorator设计模式

要解决这个问题,我的思路锁定在了这个dataSource什么是“

(二)            设计MultiDataSource类

现在回到我们的问题,我们需要对dataSource

对比原Decorator

  •     private DataSource dataSource = null;   
  • public MultiDataSource(DataSource dataSource){   
  •         this.dataSource = dataSource;   
  •     }   
  •     /* (non-Javadoc)  
  •      * @see javax.sql.DataSource#getConnection()  
  •      */  
  •     public Connection getConnection() throws SQLException {   
  •         return getDataSource().getConnection();   
  •     }   
  •     //其它DataSource接口应当实现的方法   
  •   
  •     public DataSource getDataSource(){   
  •         return this.dataSource;   
  •         }   
  •     }   
  •     public void setDataSource(DataSource dataSource) {   
  •         this.dataSource = dataSource;   
  •     }   
  • }   
    1. 客户在发出请求的时候,将dataSourceName放到request中,然后把request中的数据源名通过调用new MultiDataSource(dataSource)时可以告诉客户需要的数据源,就可以实现动态切换数据源了。但细心的朋友会发现这在单例的情况下就是问题的,因为在系统中只有一个对象,它的实例变量也只有一个,就如同一个静态变量一般。正因为如此,(三)            单例模式下的MultiDataSource

      在单例模式下,由于我们在每次调用MultiDataSource

    2.         log.debug("dataSourceName:"+dataSourceName);   
    3.         try{   
    4.             if(dataSourceName==null||dataSourceName.equals("")){   
    5.                 return this.dataSource;   
    6.             }   
    7.             return (DataSource)this.applicationContext.getBean(dataSourceName);   
    8.         }catch(NoSuchBeanDefinitionException ex){   
    9.             throw new DaoException("There is not the dataSource 
    10.         }   
    11.     }   
      1. 值得一提的是,我需要的数据源已经都在spring就是其对应的bean id="dataSource1"  

      2.     class="org.apache.commons.dbcp.BasicDataSource">  
      3.     <property name="driverClassName">  
      4.         <value>oracle.jdbc.driver.OracleDrivervalue>  
      5.     property> 
      6.     ......   
      7. bean>  
      8. <bean id="dataSource2"  
      9.     class="org.apache.commons.dbcp.BasicDataSource">  
      10.     <property name="driverClassName">  
      11.         <value>oracle.jdbc.driver.OracleDrivervalue> 
      12.     property>   
      13.     ......   
      14. bean>   
        1. 为了得到spring,并且实现方法:

          java 代码
          1. private ApplicationContext applicationContext = null;   
          2. public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {   
          3.         this.applicationContext = applicationContext;   
          4.     }   

          如此这样,我就可以通过得到了。

          (四)            通过线程传递dataSourceName

          查看以上设计,MultiDataSource

          class SpObserver {   
        2.     private static ThreadLocal local = new ThreadLocal();   
        3.     public static void putSp(String sp) {   
        4.         local.set(sp);   
        5.     }   
        6.     public static String getSp() {   
        7.         return (String)local.get();   
        8.     }   
        9. }   
          1. 做一个filter,将request中的dataSourceName对象。

          2.         String sp = SpObserver.getSp();   
          3.         return getDataSource(sp);   
          4.     }   
            1. 完整的MultiDataSource(五)            动态添加数据源

              通过以上方案,我们解决了动态分配数据源的问题,但你可能提出疑问:方案中的数据源都是配置在spring中(见附件)。不通过配置文件直接加载对象,在的源码中也有,感兴趣的朋友可以自己研究。

              (六)            在spring中配置

              在完成了所有这些设计以后,我最后再唠叨一句。我们应当在springbean id="dynamicLoadBean" class="com.htxx.service.dao.DynamicLoadBean">bean>  

            2. <bean id="dataSource" class="com.htxx.service.dao.MultiDataSource">  
            3.         <property name="dataSource">  
            4.             <ref bean="dataSource1" />  
            5.         property>  
            6.     bean>  
            7.     <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">  
            8.         <property name="dataSource">  
            9.             <ref bean="dataSource" />  
            10.         property>  
            11.         ......   
            12.     bean>  
              1. 其中dataSource以上方案与其它方案相比,它有哪些优势呢?

                首先,这个方案完全是在spring其次,实现简单,易于维护。这个方案虽然我说了这么多东西,其实都是分析,真正需要我们写的代码就只有MultiDataSource最后,这个方案可以使单数据源与多数据源兼容。这个方案完全不影响BUS相关博客:再析在spring框架中解决多数据源的问题

                example.rar
                 描述:  源码及示例
                下载
                 文件名:  example.rar
                 文件大小:  32 KB
                 下载过的:  文件被下载或查看 521 次

                关键字: Spring   Hibernate Decorator 设计模式    
                如何在spring总结多数据源的问题,其实它需要分为以下三种情况:各个数据源的数据结构不同、各个数据源的数据结构相同、各个数据源的数据结构部分相同又有部分不同。对于第二种情况,各个数据源的数据结构相同,我们使用一个sessionFactory对于各个数据源的数据结构不同的情况,使用一个sessionFactoryMultiDataSource

                 

                在该方案中,SessionFactory接口,Decorator就是MultiSessionFactorySessionFactory1SessionFactory2往往是spring。细心的朋友可能会注意,实际上并不是SessionFactory的时候其实并不是真正地得到了它,而是得到了一个SessionFactory重写了getObject()在整个这个方案中,我们需要实现的只有MultiSessionFactoryMultiSessionFactoryclass MultiSessionFactory implements SessionFactory, ApplicationContextAware {   

              2.     private static final long serialVersionUID = 2064557324203496378L;   
              3.     private static final Log log = LogFactory.getLog(MultiSessionFactory.class);   
              4.     private ApplicationContext applicationContext = null;   
              5.     private SessionFactory sessionFactory = null;   
              6.     public ApplicationContext getApplicationContext() {   
              7.         return applicationContext;   
              8.     }   
              9.     public void setApplicationContext(ApplicationContext applicationContext) {   
              10.        this.applicationContext = applicationContext;   
              11.     }   
              12.     public SessionFactory getSessionFactory(String sessionFactoryName) {   
              13.        log.debug("sessionFactoryName:"+sessionFactoryName);   
              14.        try{   
              15.            if(sessionFactoryName==null||sessionFactoryName.equals("")){   
              16.               return sessionFactory;   
              17.            }   
              18.            return (SessionFactory)this.getApplicationContext().getBean(sessionFactoryName);   
              19.        }catch(NoSuchBeanDefinitionException ex){   
              20.            throw new DaoException("There is not the sessionFactory 
              21.        }   
              22.     }   
              23.   
              24.     public SessionFactory getSessionFactory() {   
              25.        String sessionFactoryName = SpObserver.getSp();   
              26.        return getSessionFactory(sessionFactoryName);   
              27.     }   
              28.   
              29.     public void setSessionFactory(SessionFactory sessionFactory) {   
              30.        this.sessionFactory = sessionFactory;   
              31.     }   
              32.   
              33.     // SessionFactory接口需要实现的方法   
              34.   
              35. ......   
              36.   
              37. }  
                1. MultiSessionFactory的完整代码见我提供的附件。bean id="sessionFactory" class="com.htxx.service.dao.MultiSessionFactory">  

                2.     <property name="sessionFactory"><ref bean="hostSessionFactory"/>property> 
                3. >  
                  1. SpServer的写法与《如何在另外,在spring也许有些朋友对以上方案还不满意,因为在执行数据访问前毕竟还要多做一步指定sessionFactory另外,在这个方案中的核心是运用Decorator前面我已经给出了第一种和第二种情况的解决方案:各个数据源的数据结构不同的情况用MultiSessionFactory
                    example.rar
                     描述:  示例文件
                    下载
                     文件名:  example.rar
                     文件大小:  16 KB
                     下载过的:  文件被下载或查看 180 次

                    建议到原作者博客查看原文,那里有很好的回复讨论~http://fangang.javaeye.com/blog/72486
                    posted on 2007-10-15 09:53 芦苇 阅读(5396) 评论(1)  编辑  收藏 所属分类: JAVA

                    Feedback

                    # re: 如何在spring框架中解决多数据源的问题 2014-04-10 16:02 最代码
                    我整理到了最代码网站上了,有问题请回复,地址:
                    http://www.zuidaima.com/share/1774074130205696.htm  回复  更多评论
                      


                    只有注册用户登录后才能发表评论。


                    网站导航: