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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions