Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于模式的多租户:获取;java.sql.SQLException:未选择任何数据库";不时地_Java_Mysql_Spring_Spring Jdbc - Fatal编程技术网

基于模式的多租户:获取;java.sql.SQLException:未选择任何数据库";不时地

基于模式的多租户:获取;java.sql.SQLException:未选择任何数据库";不时地,java,mysql,spring,spring-jdbc,Java,Mysql,Spring,Spring Jdbc,我的代码是用Java编写的,我使用SpringJDBC模板访问MySQL数据库 我的系统是一个多租户系统,每个租户在MySQL中都有自己的专用模式(例如“租户1”、“租户2”等) 以下是初始化数据库连接的方式: 在引导过程中,我创建了一个bean,由配置了MySQL数据库连接字符串的DataSource初始化(不指定模式) 因为我的系统是多租户的,所以对于每个请求,我必须选择给定租户的模式。因此,典型的查询如下所示: “使用租户_xxx” 问题是: 有时(1到数千次处决),我会 java.sq

我的代码是用Java编写的,我使用SpringJDBC模板访问MySQL数据库

我的系统是一个多租户系统,每个租户在MySQL中都有自己的专用模式(例如“租户1”、“租户2”等)

以下是初始化数据库连接的方式:

在引导过程中,我创建了一个bean,由配置了MySQL数据库连接字符串的DataSource初始化(不指定模式)

因为我的系统是多租户的,所以对于每个请求,我必须选择给定租户的模式。因此,典型的查询如下所示:

  • “使用租户_xxx”
  • 问题是:

    有时(1到数千次处决),我会

    java.sql.SQLException:未选择任何数据库

    我仔细检查了我的代码——事实上,我总是在执行查询之前选择模式

    有什么想法吗

    • Spring-最新版本(5.x)
    • Java-11
    • MySQL(5.7),在本地MySQL和AWS Aurora上复制
    更新:添加更多信息

    • 我使用Spring引导,默认情况下使用HikariCP
    • 我在代码中的随机位置注意到了这个问题,所以它很可能不是代码中特定位置的bug
    更新2:

    • 连接器/J版本8.0

      • 有很多事情可能会出错,我将尝试提供一些一般性的想法,希望其中一些会有用

        因此,根据信息:

      • 一般思想。尝试记录sql请求,这样当错误发生时,您将看到它是否总是相同的请求/请求类型(导致代码中某些特定区域出现错误)

      • 检查您的连接池。您尚未指定实际的池,但从问题中可以清楚地看出,这不是一个“自我教育”项目或其他什么,因此您可能有一个。 有时,他们在尝试处理多租户环境时会出现错误

      • 检查在查询中添加模式名称的方法(如果适用),可能驱动程序中存在错误或其他问题(不太可能)。我是说,而不是

      • 你可以用

        select from xyz.foo
        

        如果您有连接池的配置资料,请提供

        听起来连接池是在
        USE
        和随后的DDL/DML语句之间切换连接


        还有,有没有一种方法可以将数据库分配给池条目,或者反之亦然?

        嗨,马克,我编辑了这个问题以提供更多信息。基本上,我们使用HikariCP,他们在多租户环境中肯定会有bug(我会试着问他们)。此外,我们还看到这个问题发生在多个地方,因此很可能这不是代码中的错误(至少不是查询级别的错误)。在这种情况下,还有一个普遍的想法。是否有机会将Hikari CP切换到其他池以检查问题是否仍然存在?更改应该是透明的(配置属性+依赖项)…关于使用“完全限定”表名(例如schema.table):这不是一种可伸缩的方法,因为Connector/J将每个SQL解析和缓存为“预编译”语句。此缓存是一个字典,其中键是原始SQL语句(字符串)。因此,使用完全限定的表名会将所有使用过的SQL语句作为大量模式进行重复缓存。顺便说一句,您能否发布一个小代码片段,说明您如何准确地使用jdbc模板,也许您只是以一种通常有效的错误方式进行了操作,但有时会失败……我想到了“使用”语句在一个连接上执行,但如果出现错误,实际语句将在另一个连接上执行。通常不会发生这种情况,因为从池中拾取相同的连接,但有时(多线程高负载,谁知道呢)池会为实际的sql语句提供不同的连接。。。查看一些实际代码可以帮助提供解决方案,或者建议如何检查这是否也是我们当前的工作原理。我们正在代码中进行重构,很快我们就会看到。关于池配置-没有-我们只是使用默认的Spring引导配置另一种想法。。。如果您(或Spring)未能检查错误,则可能会出现
        USE
        语句,该语句不设置数据库,而是充当自动重新连接的“ping”。自动重新连接不是一个好主意,因为它可能会搞乱事务。
        select from xyz.foo