Skip to main content
Version: 4.6

FAQ Quick Reference

This chapter collects problems that keep reappearing in the issue tracker, organized as "symptom → locate → fix". Every page lists the related historical issue numbers at the top so you can go back to the original discussion.

Before troubleshooting any switching problem, set these two things up.

Turn on the framework's own logging (it prints whether the switch succeeded or not):

logging:
level:
com.baomidou.dynamic.datasource: debug

Add one line inside your business method to see the current thread's datasource key:

String current = DynamicDataSourceContextHolder.peek();
Log / breakpoint resultMeaning
switch to the datasource named [slave_1]the key was resolved correctly, the switch happened
switch to the primary datasourceno valid key, it fell back to the primary — the problem is "the key never got pushed"
neither line / peek() is nullthe annotated method was never intercepted by AOP

Index by symptom​

SymptomRead this page
@DS is there but traffic always goes to the primary@DS not working checklist
chained queries in a Controller, IService methods do not switch@DS placement and MyBatis-Plus call styles
no switching inside @Async, thread pools or parallel streams; occasional cross-database contamination under load@DS and threads
@DS("#xxx") dynamic datasource name fails to resolveSpEL dynamic datasource names
cannot switch inside a transaction (including Spring Batch, Quartz)No switching inside a transaction
the application fails to start with driver / primary / dependency errorsStartup error quick reference

Index by topic​

TopicIn-depth documentation
@DS resolution rules, group names, precedence@DS semantics and precedence
concrete switching failure cases (Shiro, @PostConstruct, druid versions …)Troubleshooting switching failures
choosing a multi-datasource transaction strategy and the pitfalls of mixing themTransaction guide, Transaction FAQ
propagation behaviour and semantic boundaries of @DSTransactionalLocal multi-datasource transactions
pool parameter levels, version compatibility, monitoringConnection pool integration, Connection pool essentials
password encryption with ENC(...)Database password encryption
adding/removing datasources at runtimeAdding/removing datasources at runtime
the full manual switching API and its FAQManual datasource switching
read/write splitting and load balancingAutomatic read/write splitting, Custom load balancing strategy
MyBatis-Plus integrationIntegrating MyBatis-Plus

Three rules of thumb​

  1. Read the log before changing code. The framework prints the key when switching, so most "not working" cases can be classified from the log: nothing printed means it was not intercepted, primary printed means the key is wrong.
  2. Use peek() to locate the boundary. Print it at the beginning and the end of the method you suspect; that immediately separates "not intercepted" from "intercepted but the connection is already bound".
  3. Enable strict in development. spring.datasource.dynamic.strict: true makes "this datasource name does not exist" throw a CannotFindDataSourceException instead of silently falling back to the primary — the latter is the most hidden cause of "the annotation is there but the primary is always used".
spring:
datasource:
dynamic:
strict: true

Still stuck?​

  • Search or file an Issue (pasting the switch to ... line from the debug log greatly speeds up the conversation);
  • Use the Discussions board;
  • Or join the QQ group 371234236 and ask directly.