开发者社区> 问答> 正文

spring 声明式事务aop mysql读写库的配置 问题:报错

原来项目用的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   有没有人给点建议  谢谢了

展开
收起
kun坤 2020-06-07 10:26:07 823 0
1 条回答
写回答
取消 提交回答
问答排行榜
最热
最新

相关电子书

更多
云栖社区特邀专家徐雷Java Spring Boot开发实战系列课程(第20讲):经典面试题与阿里等名企内部招聘求职面试技巧 立即下载
微服务架构模式与原理Spring Cloud开发实战 立即下载
阿里特邀专家徐雷Java Spring Boot开发实战系列课程(第18讲):制作Java Docker镜像与推送到DockerHub和阿里云Docker仓库 立即下载

相关镜像