Contents

Spring 建立多個連線方法

有一部分寫到一半沒寫完。

網路上整理資料

Spring的多事务配置(多个Transaction Manager)和使用方法 - 简书

Spring的多事务配置(多个Transaction Manager)和使用方法_Clement-Xu的专栏-CSDN博客

Spring3.0配置多個事務管理器的方法 - IT閱讀

DataSource和SessionFactory的区别_Zzrdark_的博客-CSDN博客

如何在spring框架中解决多数据源的问题 - duanxz - 博客园

如何在spring框架中解决多数据源的问题_runming56的专栏-CSDN博客

The txManager bean in this case is of the HibernateTransactionManager type. In the same way as the DataSourceTransactionManager needs a reference to the DataSource, the HibernateTransactionManager needs a reference to the SessionFactory.

16. Transaction Management

13.3 Hibernate

transactionManager 預設抓 transactionManager

1
2
3
The default <tx:annotation-driven> target bean name transactionManager will still be used if no specifically qualified PlatformTransactionManager bean is found.

在配置檔案中,預設情況下,<tx:annotation-driven>會自動使用名稱為transactionManager的事務管理器。所以,如果定義的事務管理器名稱為transactionManager,那麼就可以直接使用<tx:annotation-driven/>

我公司的專案使用上面方法無效

參照Spring的多事务配置(多个Transaction Manager)和使用方法 - 简书,照上面各種設定發現我的傳案無法正常使用,後來發現Dao繼承的GenericDao裡面的SessionFactory寫死,所以上面怎麼設定都會連到,想嘗試抓現在SessionFactory,看目前沒有想到方法。

Workaround 解決方法

  1. 設定 applicationContext.xml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
 	<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> 
		<property name="jndiName"> 
			<value>java:/xxxPool</value>
			<value>java:comp/env/xxxPool</value>
		</property>
		<property name="cache" value="false" />	 
	</bean>
	
	<bean id="dataSourceHistory" class="org.springframework.jndi.JndiObjectFactoryBean"> 
		<property name="jndiName"> 
			<value>java:comp/env/xxxPool</value>
		</property>
		<property name="cache" value="false" />	 
	</bean>
	<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
		<property name="dataSource" ref="dataSource"/>
		<property name="packagesToScan" value="com.Project.persistence.entity" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">
                    org.hibernate.dialect.PostgreSQLDialect
                </prop>
                <prop key="javax.persistence.validation.mode">none</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <!-- prop key="hibernate.default_schema">Project</prop -->
                <prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop>
            </props>
        </property>
		<property name="mappingResources">
			<list>
				<value>com/Project/conf/xxxx_sql.xml</value>
			</list>
		</property>	
	</bean>
	<bean id="historySessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
		<property name="dataSource" ref="dataSourceHistory"/>
		<property name="packagesToScan" value="com.Project.persistence.history.entity" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">
                    org.hibernate.dialect.PostgreSQLDialect
                </prop>
                <prop key="javax.persistence.validation.mode">none</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.default_schema">history</prop>
                <prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop>
            </props>
        </property>
	</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
....

	<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory"/>
		<qualifier value="ProjectTx"/>
	</bean>

	<bean id="historyTransactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
		<property name="sessionFactory" ref="historySessionFactory"/>
		<qualifier value="historyTx"/>
  1. 針對原本 Bean 建立物件,去做 ForHistory名稱,原因是 packagesToScan 時候,不能用相同 Entry 名稱,所以要特別命名。

XXXX.java ==> XXXXForHistory.java

  1. 複製 GenericDaoImplGenericDaoForHistoryImpl

因為GenericDaoImpl 裡面 SessionFactory 寫死,所以為什麼上面設定怎麼調整,所以沒法修改到連線,這邊也是我目前沒辦法動態載入到連線(SessionFactory)地方。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
public class GenericDaoImpl<T> implements GenericDao<T> { 
	
	private Class<T> clazz;  
	
    public GenericDaoImpl() {  
        ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();  
        clazz = (Class<T>) type.getActualTypeArguments()[0];
    }  

    @Resource  
    private SessionFactory sessionFactory;  

改為

1
2
	@Resource  
	private SessionFactory historySessionFactory;   

https://i.imgur.com/qUkJKEr.png

@Resource可以參考 Spring 自動注入小記 | 程式狂想筆記

  1. 查詢SQL設定@Transactional另一條連線

我們這邊applicationContext.xml 有設定historyTransactionManager裡面的<qualifier value="historyTx"/>記得設定對應資料

1
@Transactional("datasource1Tx")

HibernateTransactionManager LocalEntityManagerFactoryBean 差異

https://blog.supercalifragilisticexpialidociouser.com/page/2/

yogi0209/spring-mvc-multi-datasource

尚未整理