读写分离

要求几秒钟之内有写请求,哪怕配置读数据库,也要使用master数据库


可以借助spring 的AbstractRoutingDataSource主要实现determineTargetDataSource抽象方法,去获取对应的datasource


public class DynamicDataSource extends AbstractRoutingDataSource {

    public static final String DEFAULT_DATA_SOURCE = "defaultDataSource";

    public static final List<String> dataSourceNames = new ArrayList<String>();

    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceContextHolder.getDataSourceName();
    }

    public void setTargetDataSources(Map<Object, Object> targetDataSources) {

        if (targetDataSources != null) {
            Iterator iterator = targetDataSources.keySet().iterator();

            while (iterator.hasNext()) {
                String name = (String) iterator.next();
                if (!DynamicDataSource.DEFAULT_DATA_SOURCE.equals(name)) {
                    dataSourceNames.add(name);
                }
            }
        }

        super.setTargetDataSources(targetDataSources);
    }

public class DataSourceContextHolder {

    private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();

    /**
     *
     * @param dataSourceName
     */
    public static void setDataSourceName(String dataSourceName) {
        contextHolder.set(dataSourceName);
    }

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

    /**
     * 清除只读数据源
     */
    public static void clearDataSource() {
        contextHolder.remove();
    }

    /**
     * 设置为只读数据源
     */
    public static void readDataSource() {
        readDataSource(new PollingDataSourceAdapter());
    }

    public static void readDataSource(DataSourceAdapter adapter){
        setDataSourceName(adapter.calculate(DynamicDataSource.dataSourceNames));
    }
    /**
     * 设置为只读数据源
     */
    public static void defaultDataSource() {
        setDataSourceName(DynamicDataSource.DEFAULT_DATA_SOURCE);
    }

}


aspect

 public Object switchReadOnlyDataSource(ProceedingJoinPoint joinPoint) throws Throwable {
      
        Object result = null;
        try {
            if (dataSourceHoldEnabled && DataSourceContextHolder.getDataSourceName() == null) {
                MethodSignature signature = (MethodSignature) joinPoint.getSignature();
                Method method = signature.getMethod();

                if (method.getAnnotation(ReadOnlyDataSource.class) == null||(checkWriteInReadonly&&DistributedContext.getDBWriteRecord().isUpdatedIn(dbSyncSecond))) {//写
                    DataSourceContextHolder.defaultDataSource();
                    ....
                } else {//读
                    if (dataSourceAdapter == null) {
                        DataSourceContextHolder.readDataSource();
                    } else {
                        DataSourceContextHolder.readDataSource(dataSourceAdapter);
                    }
                }
               

                

            }

            result = joinPoint.proceed();

        } finally {
            if (flag) {
                DataSourceContextHolder.clearDataSource();
            }
        }

        return result;
    }




参考:http://www.cnblogs.com/surge/p/3582248.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值