一、背景说明
准备将项目中读取数据库操作切换到从数据库上,调研方案后最终决定借助ThreadLocal实现,在测试过程中遇到间歇性异常情况,经排查是由于相同的insert、update语句会间歇性的命中到从库数据库,最终导致异常。
二、读写分离配置
原理 : 在spring-jdbc.jar包中提供了可动态切换数据源的实现类(AbstractRoutingDataSource),首先在项目中配置双数据库数据源(主数据源、从数据源)。使用AOP对dao层方法进行切割,根据方法名称判断,当方法名称为只读方法时将ThreadLocal中存储的数据源标签设置为read数据源( 从数据源名称)。重写AbstractRoutingDataSource中的determineCurrentLookupKey钩子方法,读取ThreadLocal中存储的数据源标签名称返回,最终实现数据库的读写分离。
ThreadLocal工具类代码如下所示
public class DbTagUtil {
private static ThreadLocal<String> dbTagLocal = new ThreadLocal<String>();
public static final String READ = "read";
public static final String WRITE = "write";
public static String getDbTag() {
String db = dbTagLocal.get();
if (db == null) {
/**默认写库**/
db = WRITE;
}
return