基于模式的多租户:不时获得 "java.sql.SQLException: No database selected"
Schema-based multitenancy: getting "java.sql.SQLException: No database selected" from time to time
我的代码是用 Java 编写的,我使用 Spring JDBC 模板访问 MySQL 数据库。
我的系统是一个多租户系统,每个租户在 MySQL 中都有自己的专用模式(例如 "tenant_1"、"tenant_2" 等)。
这是初始化数据库连接的方式:
在 bootstrap 期间,我创建了一个公开的 bean DataSourceTransactionManager,它由配置有 MySQL 数据库的连接字符串(未指定架构)的 DataSource 初始化。
由于我的系统是多租户的,对于每个请求我都必须 select 给定租户的架构。因此,典型的查询如下所示:
- "USE tenant_xxx"
- ..
问题:
不时(1 到数千次执行),我得到
java.sql.SQLException: No database selected.
我仔细检查了我的代码 - 事实上,我总是在执行查询之前 selecting 架构。
有什么想法吗?
- Spring - 最新版本 (5.x)
- Java - 11
- MySQL (5.7),在本地 MySQL 和 AWS Aurora
上重现
更新:添加更多信息
- 我使用Spring引导,默认使用HikariCP
- 我在代码中的随机位置注意到了这个问题,所以它很可能不是 我的代码
中特定位置的错误
更新 2:
- Connector/J 版本 8.0
有很多事情可能会出错,我将尝试提供一般性想法,希望其中一些有用。
所以,鉴于信息:
总体思路。尝试记录 sql 请求,这样当错误发生时,您将看到它是否总是相同的请求/请求类型(导致代码某些特定区域出现错误的东西)。
检查你的连接池。您尚未指定实际池,但从问题中可以清楚地看出它不是 "self-education" 项目或其他项目,因此您可能有一个。
有时他们在尝试处理多租户环境时会遇到错误。
检查在查询中添加架构名称的方法(如果适用),可能是驱动程序中存在错误或其他问题(不太可能)。我的意思是,而不是
USE XYZ
select * from foo
你可以使用
select from xyz.foo
如果您有连接池的配置资料,请提供。
听起来连接池正在 USE
和后续 DDL/DML 语句之间切换连接。
另外,有没有办法将数据库分配给池条目,反之亦然?
我的代码是用 Java 编写的,我使用 Spring JDBC 模板访问 MySQL 数据库。
我的系统是一个多租户系统,每个租户在 MySQL 中都有自己的专用模式(例如 "tenant_1"、"tenant_2" 等)。
这是初始化数据库连接的方式:
在 bootstrap 期间,我创建了一个公开的 bean DataSourceTransactionManager,它由配置有 MySQL 数据库的连接字符串(未指定架构)的 DataSource 初始化。
由于我的系统是多租户的,对于每个请求我都必须 select 给定租户的架构。因此,典型的查询如下所示:
- "USE tenant_xxx"
- ..
问题:
不时(1 到数千次执行),我得到
java.sql.SQLException: No database selected.
我仔细检查了我的代码 - 事实上,我总是在执行查询之前 selecting 架构。
有什么想法吗?
- Spring - 最新版本 (5.x)
- Java - 11
- MySQL (5.7),在本地 MySQL 和 AWS Aurora 上重现
更新:添加更多信息
- 我使用Spring引导,默认使用HikariCP
- 我在代码中的随机位置注意到了这个问题,所以它很可能不是 我的代码 中特定位置的错误
更新 2:
- Connector/J 版本 8.0
有很多事情可能会出错,我将尝试提供一般性想法,希望其中一些有用。
所以,鉴于信息:
总体思路。尝试记录 sql 请求,这样当错误发生时,您将看到它是否总是相同的请求/请求类型(导致代码某些特定区域出现错误的东西)。
检查你的连接池。您尚未指定实际池,但从问题中可以清楚地看出它不是 "self-education" 项目或其他项目,因此您可能有一个。 有时他们在尝试处理多租户环境时会遇到错误。
检查在查询中添加架构名称的方法(如果适用),可能是驱动程序中存在错误或其他问题(不太可能)。我的意思是,而不是
USE XYZ
select * from foo
你可以使用
select from xyz.foo
如果您有连接池的配置资料,请提供。
听起来连接池正在 USE
和后续 DDL/DML 语句之间切换连接。
另外,有没有办法将数据库分配给池条目,反之亦然?