多线程ThreadLocal使用中异常错误:
public abstract class CustomerContextHolder {
public final static String SESSION_FACTORY_PORTAL1 = "portal1";
public final static String SESSION_FACTORY_BO1 = "bo1";
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
public static void setContextType(String contextType) {
contextHolder.set(contextType);
}
public static String getContextType() {
return contextHolder.get();
}
public static void clearContextType() {
contextHolder.remove();
}
}
CustomerContextHolder.setContextType(CustomerContextHolder.SESSION_FACTORY_PORTAL1);
List<SellLimit> sellLimitList = sellLimitMapper.selectUpdateLimit(params);
//切换其他数据源
CustomerContextHolder.setContextType(idCompart);
List<SellLimit> sellLimitList = sellLimitMapper.selectUpdateLimit(params);
1.系统采用的是分库的方式,进行数据处理时候会进行数据源切换。有db1,db2,db3,db4等数据源。
2.web应用服务器中使用线程池,核心线程20个。
3.请求A到web服务器,经过逻辑判断,切换数据源到db2,tomcat线程池分配的线程是thread2,然后在线程threadlocal.setcontent(db2)方法存放db2数据源变量。进行业务处理,放回线程池此线程。
4.请求B到web服务器,进行业务逻辑处理,使用默认数据源,不进行切换分库,由于线程池复用的,然后tomcat线程池分配的线程是thread2,该线程threadlocal存放的仍然是db2数据源,进行业务处理就会报错。
5.每次使用threadlocal.setcontent(db2)方法之后,需要调用threadlocal.remove方法进行变量的销毁。
注意:此错误会随着并发量的大小而出现的,偶然的,但是根据具体的逻辑就可以定位到的。