在父子容器中都存在數據源的配置,父容器中採用默認名稱“dataSource”作爲id,子容器開發的使用者在配置數據源時並不知道父容器的配置,導致數據源的id一樣,這時候就拋出了DataSource is Closed的錯誤消息,隨後修改子容器的數據源名稱爲dataSourceWidgetpt,這個錯誤解決,但是此時在子容器中配置事務發現,事務失效。
父子容器的數據源配置圖和事務失效原因:
下面是Spring的配置文件,紅色註釋要注意:
<?xml version="1.0" encoding="GBK"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
default-autowire="byName">
<!-- 以後其他模塊也需要DataSource的話,統一移到到common模塊(需要新建的) -->
<bean id="dataSourceWidgetpt" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.alibaba.china.jdbc.SimpleDriver" />
<property name="url" value="${widgetpt_database_driver_url}" />
<property name="username" value="${widgetpt_database_driver_username}" />
<property name="password">
<bean
class="com.alibaba.china.galaxy.common.spring.MapChooseValueFactoryBean">
<property name="key" value="${widgetpt_production}" />
<property name="objects">
<map>
<entry key="run">
<bean
class="com.alibaba.china.biz.common.security.EncryptDBPasswordFactory">
<property name="password"
value="${widgetpt_database_driver_password_encrypted}" />
</bean>
</entry>
<entry key="dev" value="${widgetpt_database_driver_password}" />
<entry key="test" value="${widgetpt_database_driver_password}" />
</map>
</property>
</bean>
</property>
<property name="maxActive">
<value>14</value>
</property>
<property name="initialSize">
<value>1</value>
</property>
<property name="maxWait">
<value>60000</value>
</property>
<property name="maxIdle">
<value>14</value>
</property>
<property name="minIdle">
<value>1</value>
</property>
<property name="removeAbandoned">
<value>true</value>
</property>
<property name="removeAbandonedTimeout">
<value>180</value>
</property>
<property name="timeBetweenEvictionRunsMillis">
<value>60000</value>
</property>
<property name="minEvictableIdleTimeMillis">
<value>1800000</value>
</property>
<property name="connectionProperties">
<value>bigStringTryClob=true;clientEncoding=GBK;defaultRowPrefetch=50;serverEncoding=ISO-8859-1</value>
</property>
</bean>
<!-- spring 事務回滾需要用到的事務管理器。 -->
<bean name="transactionManagerWidgetpt"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSourceWidgetpt" />
</bean>
<bean id="transactionBaseWidgetpt"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
lazy-init="true" abstract="true">
<!-- 配置事務管理器 -->
<property name="transactionManager" ref="transactionManagerWidgetpt" />
<!-- 配置事務屬性 -->
<property name="transactionAttributes">
<props>
<prop key="upload*">PROPAGATION_REQUIRED,-Exception</prop>
<prop key="publish*">PROPAGATION_REQUIRED,-Exception</prop>
</props>
</property>
</bean>
<!-- <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager" /> </bean> -->
</beans>
下面是DAO和Service的配置
<bean id="pluginConfigServicetarget" class="com.alibaba.widgetpt.plugin.PluginConfigServiceImpl" />
<import resource="classpath:spring/widgetpt-datasource-oracle.xml" />
<bean id="pluginConfigService" parent="transactionBaseWidgetpt">
<property name="target" ref="pluginConfigServicetarget" />
</bean>
<!-- 默認的sqlMapClient,數據源爲oracle -->
<bean id="sqlMapClientWidgetpt" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<!-- 這裏也支持數據源配置,但是不能配置在sqlMapClient中需要配置在下面的sqlMapClientDAO中,原因可以看後面的解釋圖 -->
<property name="configLocation" value="classpath:sqlmap/widgetpt-default-sqlmap.xml" />
</bean>
<bean id="sqlMapClientDAO" abstract="true">
<!-- 數據源一定要配置在這裏,不能配置在上面的sqlMapClientWidgetpt中 -->
<property name="dataSource" ref="dataSourceWidgetpt" />
<property name="sqlMapClient" ref="sqlMapClientWidgetpt" />
</bean>
<bean id="pluginSummaryDAO" parent="sqlMapClientDAO"
class="com.alibaba.widgetpt.plugin.config.dao.support.IBatisPluginSummaryDAO" />
<bean id="pluginManageDAO" parent="sqlMapClientDAO"
class="com.alibaba.widgetpt.plugin.config.dao.support.IBatisPluginManageDAO" />
<bean id="pluginHistoryDAO" parent="sqlMapClientDAO"
class="com.alibaba.widgetpt.plugin.config.dao.support.IBatisPluginHistoryDAO" />
<bean id="pluginResourceDAO" parent="sqlMapClientDAO"
class="com.alibaba.widgetpt.plugin.config.dao.support.IBatisPluginResourceDAO" />
<bean id="pluginSiteInfoDAO" parent="sqlMapClientDAO"
class="com.alibaba.widgetpt.plugin.config.dao.support.IBatisPluginSiteInfoDAO" />
<import resource="classpath:spring/widgetpt-normandy-beans.xml" />
</beans>