Skip to content

[xxx] 整合MyBatis-plus的dynamic多数据源发生Too many connections #847

@AFatFox

Description

@AFatFox

Description

我在使用多数据源的情况下,尝试整合MyBatis-plus的多数据源的情况下出现了点问题,是这样的,我们项目中除了使用apijson外,也需要自己进行写一些增删改的接口,而且也要支持多数据源,所以这里我尝试整合MyBatis-plus的多数据源,我初步是整合成功了,通过apijson和自己写的接口,都可进行多数据源的增删改查,但是出现了一些问题,当项目使用一段时间,控制台就会报错:Too many connections(MySQL 错误码 1040)就是数据库连接太多了,比如我通过一直调用apijson的get方法,调用一两百次,就会复现这个问题,我怀疑是没有正常关闭连接的问题,但是我始终找不到问题点在哪里,为了实现两者整合,我重写了DemoSQLExecutor的getConnection方法,以可以从MyBatis-plus的多数据源地方获取DataSource,然后取消了原本的通过DemoDataSourceConfig的@bean方式注入DruidDataSource的代码,然后修改了一下配置,改动如下
请问Tommy哥,这种情况有办法解决吗?
环境:Java21+SpringBoot3.2.5+MySQL8.0.24+dynamic-datasource4.3.1(MyBatis-plus的多数据源包)

重写的DemoSQLExecutor的getConnection方法
@OverRide
public Connection getConnection(SQLConfig config) throws Exception {
String key = config.getDatasource() + "-" + config.getDatabase();
Connection c = connectionMap.get(key);
if (c == null || c.isClosed()) {

		// 获取 Spring 上下文和 Environment
		ApplicationContext ctx = DemoApplication.getApplicationContext();
		if (ctx == null) {
			throw new IllegalStateException("无法获取 Spring ApplicationContext");
		}
		Environment env = ctx.getEnvironment();

		// 3) 获取要使用的 dataSource 名(前端通过@datasource来指定)
		String requested = config.getDatasource();
		DataSource ds = null;

		Map<String, DataSource> provided = new HashMap<>();
		// 如果容器有 DynamicDataSourceProvider bean(starter 情况),直接取出 provider 管理的 map
		if (ctx.getBeanNamesForType(DynamicDataSourceProvider.class).length > 0) {
			DynamicDataSourceProvider provider = ctx.getBean(DynamicDataSourceProvider.class);
			provided = provider.loadDataSources();
			ds = provided.get(requested);
		}

		// 4) 如果没找到,尝试从配置读取默认数据源名(spring.datasource.dynamic.primary)
		if (ds == null) {
			String primaryName = null;
			try {
				primaryName = env.getProperty("spring.datasource.dynamic.primary");
			} catch (Throwable ignored) {}
			if (primaryName != null && !primaryName.isBlank()) {
				ds = provided.get(primaryName);
			}
		}

		// 5) 最后兜底:如果 ds 仍然为空且 dsMap 只有一个元素,则取唯一那个
		if (ds == null && provided.size() == 1) {
			ds = provided.values().iterator().next();
		}

		// 7) 获取连接并缓存(保留原先的 connectionMap 逻辑)
		connectionMap.put(key, ds == null ? null : ds.getConnection());
	}

	// 保持原来的逻辑:必须最后执行 super.getConnection(config)
	return super.getConnection(config);
}

配置:
spring:
datasource:
dynamic:
primary: druid # 指定默认数据源名称
datasource:
druid:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/office_automation?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
druid-test:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://14.70.22.777:33336/office_automation?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8
username: ENC(fXGOMv7Vggup2KAbAyHoI6Mzd7lqblJdxi1CSt8CZvAjGHen5rAj6HiwKt5W)
password: ENC(n24kDLyLtsv2HJCpwhKzIJycd/UD+NYy88c2haiS7mIUj0S/2Am8sQ==)
type: com.alibaba.druid.pool.DruidDataSource

MyBatis-plus的多数据源依赖包的坐标:

	<dependency>
		<groupId>com.baomidou</groupId>
		<artifactId>dynamic-datasource-spring-boot3-starter</artifactId>
		<version>4.3.1</version>
	</dependency>

DemoDataSourceConfig类中的代码全部注释掉了

报错信息:

Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions