Java
9339 1094

Sharding Jdbc强制路由主库

Cyber
Cyber 发布于 2024-11-12 15:59:12
JavaSharding

Sharding JDBC 主从模式下,查询使用从库,添加更新以及删除数据操作时使用主库,但是在某些实时性比较高的场景,因为主从延时,从库还未同步数据,导致查询不到数据,因此需要强制路由到主库。

在官网教程中,可以使用hintManager.setMasterRouteOnly设置主库路由。设置主库路由

示例:

String sql = "SELECT * FROM t_order";
try (
        HintManager hintManager = HintManager.getInstance();
        Connection conn = dataSource.getConnection();
        PreparedStatement preparedStatement = conn.prepareStatement(sql)) {
    hintManager.setMasterRouteOnly();
    try (ResultSet rs = preparedStatement.executeQuery()) {
        while (rs.next()) {
            // ...
        }
    }
}

实际为了更好的使用,需要封装一个注解,使用AOP来动态设置

环境: SpringBoot、MyBatis-Plus、Sharding-JDBC

定义一个注解,@ShardingMaster,用于标注该方法使用主库数据源(这里为Master)

/**
 * sharding数据源 强制读取主库
 */
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@DS("sharding")  //这里指定了数据源为 sharding
public @interface ShardingMaster {
}

定义一个切面 ShardingMasterAspect

@Component
@Aspect
public class ShardingMasterAspect {

    //路径改为实际 @ShardingMaster路径
    @Pointcut("@annotation(com.xx.xx.ShardingMaster)")
    public void pointcut() {
    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();
        Object ret = null;
        HintManager.clear();
        try (HintManager hintManager = HintManager.getInstance()) {
            //强制路由主库
            hintManager.setWriteRouteOnly();
            ret = joinPoint.proceed(args);
        }

        return ret;
    }

}

使用:

@ShardingMaster
public void shardingMasterTest() {
	//to do someing...
}