問題的分析
我首先想到在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;
}
}
客戶在發出請求的時候,將dataSourceName放到request中,然后把request中的數據源名通過調用new MultiDataSource(dataSource)時可以告訴客戶需要的數據源,就可以實現動態切換數據源了。但細心的朋友會發現這在單例的情況下就是問題的,因為在系統中只有一個對象,它的實例變量也只有一個,就如同一個靜態變量一般。正因為如此,(三) 單例模式下的MultiDataSource
在單例模式下,由于我們在每次調用MultiDataSource
log.debug("dataSourceName:"+dataSourceName);
try{
if(dataSourceName==null||dataSourceName.equals("")){
return this.dataSource;
}
return (DataSource)this.applicationContext.getBean(dataSourceName);
}catch(NoSuchBeanDefinitionException ex){
throw new DaoException("There is not the dataSource
}
}
值得一提的是,我需要的數據源已經都在spring就是其對應的bean id="dataSource1"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName">
<value>oracle.jdbc.driver.OracleDrivervalue>
property>
......
bean>
<bean id="dataSource2"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName">
<value>oracle.jdbc.driver.OracleDrivervalue>
property>
......
bean>
為了得到spring,并且實現方法:
java 代碼
- private ApplicationContext applicationContext = null;
- public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
- this.applicationContext = applicationContext;
- }
如此這樣,我就可以通過得到了。
(四) 通過線程傳遞dataSourceName
查看以上設計,MultiDataSource
class SpObserver {
private static ThreadLocal local = new ThreadLocal();
public static void putSp(String sp) {
local.set(sp);
}
public static String getSp() {
return (String)local.get();
}
}
做一個filter,將request中的dataSourceName對象。
String sp = SpObserver.getSp();
return getDataSource(sp);
}
完整的MultiDataSource(五) 動態添加數據源
通過以上方案,我們解決了動態分配數據源的問題,但你可能提出疑問:方案中的數據源都是配置在spring中(見附件)。不通過配置文件直接加載對象,在的源碼中也有,感興趣的朋友可以自己研究。
(六) 在spring中配置
在完成了所有這些設計以后,我最后再嘮叨一句。我們應當在springbean id="dynamicLoadBean" class="com.htxx.service.dao.DynamicLoadBean">bean>
<bean id="dataSource" class="com.htxx.service.dao.MultiDataSource">
<property name="dataSource">
<ref bean="dataSource1" />
property>
bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
property>
......
bean>
其中dataSource以上方案與其它方案相比,它有哪些優勢呢?
首先,這個方案完全是在spring其次,實現簡單,易于維護。這個方案雖然我說了這么多東西,其實都是分析,真正需要我們寫的代碼就只有MultiDataSource最后,這個方案可以使單數據源與多數據源兼容。這個方案完全不影響BUS相關博客:再析在spring框架中解決多數據源的問題
|
example.rar |
描述: |
源碼及示例 |

下載 |
文件名: |
example.rar |
文件大小: |
32 KB |
下載過的: |
文件被下載或查看 521 次 |
關鍵字: Spring Hibernate Decorator 設計模式
如何在spring總結多數據源的問題,其實它需要分為以下三種情況:各個數據源的數據結構不同、各個數據源的數據結構相同、各個數據源的數據結構部分相同又有部分不同。對于第二種情況,各個數據源的數據結構相同,我們使用一個sessionFactory對于各個數據源的數據結構不同的情況,使用一個sessionFactory與MultiDataSource

在該方案中,SessionFactory接口,Decorator就是MultiSessionFactory,SessionFactory1和SessionFactory2往往是spring的。細心的朋友可能會注意,實際上并不是SessionFactory的時候其實并不是真正地得到了它,而是得到了一個SessionFactory重寫了getObject()。在整個這個方案中,我們需要實現的只有MultiSessionFactory。MultiSessionFactoryclass MultiSessionFactory implements SessionFactory, ApplicationContextAware {
private static final long serialVersionUID = 2064557324203496378L;
private static final Log log = LogFactory.getLog(MultiSessionFactory.class);
private ApplicationContext applicationContext = null;
private SessionFactory sessionFactory = null;
public ApplicationContext getApplicationContext() {
return applicationContext;
}
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
public SessionFactory getSessionFactory(String sessionFactoryName) {
log.debug("sessionFactoryName:"+sessionFactoryName);
try{
if(sessionFactoryName==null||sessionFactoryName.equals("")){
return sessionFactory;
}
return (SessionFactory)this.getApplicationContext().getBean(sessionFactoryName);
}catch(NoSuchBeanDefinitionException ex){
throw new DaoException("There is not the sessionFactory
}
}
public SessionFactory getSessionFactory() {
String sessionFactoryName = SpObserver.getSp();
return getSessionFactory(sessionFactoryName);
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
// SessionFactory接口需要實現的方法
......
}
MultiSessionFactory的完整代碼見我提供的附件。bean id="sessionFactory" class="com.htxx.service.dao.MultiSessionFactory">
<property name="sessionFactory"><ref bean="hostSessionFactory"/>property>
>
SpServer的寫法與《如何在另外,在spring也許有些朋友對以上方案還不滿意,因為在執行數據訪問前畢竟還要多做一步指定sessionFactory另外,在這個方案中的核心是運用Decorator前面我已經給出了第一種和第二種情況的解決方案:各個數據源的數據結構不同的情況用MultiSessionFactory
example.rar |
描述: |
示例文件 |

下載 |
文件名: |
example.rar |
文件大小: |
16 KB |
下載過的: |
文件被下載或查看 180 次 |
|
建議到原作者博客查看原文,那里有很好的回復討論~http://fangang.javaeye.com/blog/72486