读写分离实现

技术框架式springmvc + mybatis


一:路由主从库数据源实现(核心代码)


public class MasterSlaveRoutingDataSource extends AbstractRoutingDataSource {
	private static  AtomicInteger counter = new AtomicInteger(0);
	private String[] readDataSourceKeys;


	@Override
	protected Object determineCurrentLookupKey() {
		counter.incrementAndGet();
		String dataSourceKey = DataSourceContextHolder.WRITE;
		String type = DataSourceContextHolder.getDbType();
		if(null != type && DataSourceContextHolder.READ.equals(type))
			dataSourceKey = type;
		return dataSourceKey;
/*
			if(DataSourceContextHolder.READ.equals(type)){
				dataSourceKey = randomReadDataSourceKey();
			}

			return dataSourceKey;*/
	}

	public String randomReadDataSourceKey(){
		if(readDataSourceKeys == null|| readDataSourceKeys.length == 0){
			throw new RuntimeException("readDataSourceKeys is empty");
		}
		return readDataSourceKeys[(int)(Math.random() * readDataSourceKeys.length)];
	}

	public String[] getReadDataSourceKeys() {
		return readDataSourceKeys;
	}

	public void setReadDataSourceKeys(String[] readDataSourceKeys) {
		this.readDataSourceKeys = readDataSourceKeys;
	}



}


二:选择主从数据源实现

public class DataSourceContextHolder {

    private static final ThreadLocal
   
   
    
     contextHolder = new ThreadLocal
    
    
     
     ();

    public static final String READ = "READ";
    public static final String WRITE = "WRITE";

    public static void setCustomerType(String type) {
        //contextHolder.remove();
        if(getDbType() == null){
            contextHolder.set(type);
        }
    }

    /**
     * @param type
     */
    public static void directSetCustomerType(String type) {
        contextHolder.remove();
        contextHolder.set(type);
    }

    public static String getDbType() {
        return  contextHolder.get();
    }

    public static void clearType() {
        contextHolder.remove();
    }
}
    
    
   
   


三:在哪里选择数据源--切面实现(service层)

public class ReadWriteAspect {

    /**
     * @return
     * @throws Throwable
     */
    public void selectReadWriteDataSource(final JoinPoint point) throws Throwable {
        DataSourceContextHolder.directSetCustomerType(DataSourceContextHolder.WRITE);
        if(null != point && null !=  point.getSignature() && null != point.getSignature().getName()){
            String methodName = point.getSignature().getName();
            String reg = "^get|^find|^select|^parse|^check";
            Pattern pattern = Pattern.compile(reg);
            Matcher matcher = pattern.matcher(methodName);
            if(matcher.find())
                DataSourceContextHolder.directSetCustomerType(DataSourceContextHolder.READ);
        }
    }

    /**
     * @throws Throwable
     */
    public void clearReadWriteDataSource() throws Throwable {
        DataSourceContextHolder.clearType();
    }

}

四:事物和选择数据源的顺序 实现 (service层)



   
   

   
   

    
    
    
        
     
     
        
     
     
        
     
     
        
     
     
        
     
     
        
     
     
        
     
     
        
     
     
        
     
     
        
     
     
        
     
     
        
     
     
        
     
     
    
    
    


    
    
    
        
     
     
        
     
     
        
     
     
        
     
     
        
     
     
        
     
     
        
     
     
        
     
     
        
     
     
        
     
     
        
     
     
        
     
     
        
     
     
    
    
    

    
    
    
    
    
    
        
     
     
            
      
      
                
       
       
                
       
       
            
        
     
     
        
     
     
        
     
     
    
    
    


   
   



   
   

   
   

	
    
    

	
    
    

	
    
    
		
     
     
			
      
      
			
      
      
			
      
      
		
     
     
	
    
    

	
    
    
	
    
    
		
     
     
	
    
    

	
    
    



   
   


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值