开发者社区> 问答> 正文

spring 声明式事务aop mysql读写库的配置 问题 403.10 禁止访问:配置无效 

原来项目用的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的接口类上

展开
收起
kun坤 2020-05-28 13:26:19 638 0
1 条回答
写回答
取消 提交回答
  • @DataSource("read")
        public List<Page>findForIndex();
    结果有时候是用read有时候用write   有没有人给点建议  谢谢了

    m

    2020-05-28 14:48:02
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
One Box: 解读事务与分析一体化数据库 HybridDB for MySQL 立即下载
One Box:解读事务与分析一体化数据库HybridDB for MySQL 立即下载
如何支撑HTAP场景-HybridDB for MySQL系统架构和技术演进 立即下载

相关镜像