原来项目用的spring声明式事务处理 现在需要加上mysql的读写库 应用层使用的是aop切换数据库连接 但是读的时候有时候是读库 有时候是写库 不知道是否和声明式事务处理有关 各位大大帮忙看看
applicationContext.xml
<!-- 主库数据源 -->
<bean id="writeDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${slave.jdbc.driver}" /><.....省略配置>
</bean>
<!-- 从库数据源 -->
<bean id="readDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${slave.jdbc.driver}" /><.....省略配置>
</bean>
<bean id="dataSource" class="(这里省略).ChooseDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<!-- write -->
<entry key="write" value-ref="writeDataSource"/>
<!-- read -->
<entry key="read" value-ref="readDataSource"/>
</map>
</property>
<property name="defaultTargetDataSource" ref="writeDataSource"/>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- Mybatis's sqlSessionFactory config -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:/mapper/Configuration.xml" />
<property name="mapperLocations" value="classpath:/mapper/*Mapper.xml" />
</bean>
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="(这边省略).*.dao.mapper" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
<!--事务管理器 -->
<bean name="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置事务通知 -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT" />
<!-- <tx:method name="set*" propagation="REQUIRED" isolation="DEFAULT" /> -->
<...省略...>
<tx:method name="find*" propagation="REQUIRED" isolation="DEFAULT" read-only="true" />
<tx:method name="select*" propagation="REQUIRED" isolation="DEFAULT" read-only="true" />
<tx:method name="*" read-only="true" />
</tx:attributes>
</tx:advice>
<bean id="dataSourceAspect" class="(这边省略).aspect.DataSourceAspect"></bean>
<!-- aop事务配置 -->
<aop:config>
<aop:pointcut id="txPointcut" expression="execution(* *..*Service.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
<aop:aspect id="c" ref="dataSourceAspect">
<aop:pointcut id="changeData" expression="execution(* *..*Service.*(..))"/>
<aop:before pointcut-ref="changeData" method="before"/>
</aop:aspect>
</aop:config>
spring aop 动态选取
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface DataSource { String value(); }
多数据源
public class ChooseDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return HandleDataSource.getDataSource(); } }
ThreadLocal
public class HandleDataSource { public static final ThreadLocal<String> holder = new ThreadLocal<String>(); public static void putDataSource(String datasource) { holder.set(datasource); } public static String getDataSource() { return holder.get(); } }
切面类
public class DataSourceAspect { public void pointCut(){}; public void before(JoinPoint point) { Object target = point.getTarget(); System.out.println(target.toString()); String method = point.getSignature().getName(); System.out.println(method); Class<?>[] classz = target.getClass().getInterfaces(); Class<?>[] parameterTypes = ((MethodSignature) point.getSignature()) .getMethod().getParameterTypes(); try { Method m = classz[0].getMethod(method, parameterTypes); System.out.println(m.getName()); if (m != null && m.isAnnotationPresent(DataSource.class)) { DataSource data = m.getAnnotation(DataSource.class); HandleDataSource.putDataSource(data.value()); } } catch (Exception e) { e.printStackTrace(); } } }
接着在service的接口类上
@DataSource("read") public List<Page>findForIndex();
结果有时候是用read有时候用write 有没有人给点建议 谢谢了
原来项目用的spring声明式事务处理 现在需要加上mysql的读写库 应用层使用的是aop切换数据库连接 但是读的时候有时候是读库 有时候是写库 不知道是否和声明式事务处理有关 各位大大帮忙看看
applicationContext.xml
<!-- 主库数据源 -->
<bean id="writeDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${slave.jdbc.driver}" /><.....省略配置>
</bean>
<!-- 从库数据源 -->
<bean id="readDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${slave.jdbc.driver}" /><.....省略配置>
</bean>
<bean id="dataSource" class="(这里省略).ChooseDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<!-- write -->
<entry key="write" value-ref="writeDataSource"/>
<!-- read -->
<entry key="read" value-ref="readDataSource"/>
</map>
</property>
<property name="defaultTargetDataSource" ref="writeDataSource"/>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- Mybatis's sqlSessionFactory config -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:/mapper/Configuration.xml" />
<property name="mapperLocations" value="classpath:/mapper/*Mapper.xml" />
</bean>
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="(这边省略).*.dao.mapper" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
<!--事务管理器 -->
<bean name="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置事务通知 -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT" />
<!-- <tx:method name="set*" propagation="REQUIRED" isolation="DEFAULT" /> -->
<...省略...>
<tx:method name="find*" propagation="REQUIRED" isolation="DEFAULT" read-only="true" />
<tx:method name="select*" propagation="REQUIRED" isolation="DEFAULT" read-only="true" />
<tx:method name="*" read-only="true" />
</tx:attributes>
</tx:advice>
<bean id="dataSourceAspect" class="(这边省略).aspect.DataSourceAspect"></bean>
<!-- aop事务配置 -->
<aop:config>
<aop:pointcut id="txPointcut" expression="execution(* *..*Service.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
<aop:aspect id="c" ref="dataSourceAspect">
<aop:pointcut id="changeData" expression="execution(* *..*Service.*(..))"/>
<aop:before pointcut-ref="changeData" method="before"/>
</aop:aspect>
</aop:config>
spring aop 动态选取
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface DataSource { String value(); }
多数据源
public class ChooseDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return HandleDataSource.getDataSource(); } }
ThreadLocal
public class HandleDataSource { public static final ThreadLocal<String> holder = new ThreadLocal<String>(); public static void putDataSource(String datasource) { holder.set(datasource); } public static String getDataSource() { return holder.get(); } }
切面类
public class DataSourceAspect { public void pointCut(){}; public void before(JoinPoint point) { Object target = point.getTarget(); System.out.println(target.toString()); String method = point.getSignature().getName(); System.out.println(method); Class<?>[] classz = target.getClass().getInterfaces(); Class<?>[] parameterTypes = ((MethodSignature) point.getSignature()) .getMethod().getParameterTypes(); try { Method m = classz[0].getMethod(method, parameterTypes); System.out.println(m.getName()); if (m != null && m.isAnnotationPresent(DataSource.class)) { DataSource data = m.getAnnotation(DataSource.class); HandleDataSource.putDataSource(data.value()); } } catch (Exception e) { e.printStackTrace(); } } }
接着在service的接口类上
@DataSource("read") public List<Page>findForIndex();
结果有时候是用read有时候用write 有没有人给点建议 谢谢了
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。