Hibernate3.6 SessionFactory集成AbstractRoutingDataSource切换主从数据源异常
根因分析
- 事务连接复用机制限制:Hibernate 3.6的Session会在事务启动时一次性获取JDBC连接,整个事务生命周期内会复用该连接,不会再次调用
determineTargetDataSource获取新连接。你切换数据源标识的时机晚于事务开启时,就会出现标识正确但实际连接未切换的问题,表现为随机路由。 - ThreadLocal值污染:你没有对ThreadLocal变量做请求结束后的清理逻辑,web容器的线程池复用机制会导致上一个请求设置的数据源标识残留到下一个请求,最终获取到错误的数据源连接。
- 连接配置不匹配:你遇到的
no pg_hba.conf entry报错是因为RDS PostgreSQL默认要求SSL连接,当ThreadLocal被污染切换到未配置SSL参数的数据源时,连接请求会被数据库的访问规则拒绝。
修复方案
- 调整数据源切换时机:通过Spring拦截器或者Servlet过滤器,在请求进入业务逻辑、事务开启前,就根据请求的读写属性提前调用
setReadonlyDataSource设置对应标识。 - 新增ThreadLocal清理逻辑:在拦截器/过滤器的请求结束回调方法(比如
afterCompletion)中调用MasterReplicaRoutingDataSource.currentDataSource.remove(),清空当前线程的数据源标识,避免线程复用带来的污染。 - 统一数据源连接配置:检查主库和副本两个数据源的JDBC连接参数,补充RDS PostgreSQL要求的SSL配置,比如在URL后添加
ssl=true&sslmode=require参数,确保两个数据源都能正常建立连接。 - 调整Session开启时机:如果项目配置了
OpenSessionInViewFilter/OpenSessionInViewInterceptor,要确保数据源切换逻辑的执行顺序早于Session开启的逻辑,避免Session获取连接时还未设置正确的数据源标识。
内容的提问来源于stack exchange,提问作者learner
相关产品推荐
相关产品推荐

