【问题标题】:Possible concurrency conflict in getConnection() under multitenancy situation多租户情况下 getConnection() 中可能存在并发冲突
【发布时间】:2021-07-07 00:06:48
【问题描述】:

我正在实施基于数据库模式的多租户策略。我使用 PostgreSQL for db,HikariCP for pool,它是一个 SpringBoot 应用程序。获得连接后,我需要设置架构,如下面的代码。 (this.ds 是一个光池)

@Override public Connection getConnection() throws SQLException {
    Connection connection = this.ds.getConnection();

    // reset target schema to...
    String schema = determineSchema();
    connection.createStatement().execute("SET search_path to "+schema);

    return connection;
}

所以我的问题是,假设与tenant1 和tenant2 的两个API 调用几乎同时访问getConnection() 函数并设置模式。我想知道代码将如何处理它?理想情况下,我希望 Hikari 会给他们 2 个不同的连接,并且模式集中不会有冲突。但这是真实的情况吗?我们这里需要读/写锁吗?先谢谢了。

【问题讨论】:

    标签: spring-boot concurrency schema multi-tenant hikaricp


    【解决方案1】:

    连接池会跟踪它已签出的连接;一旦一个连接被移交给一个线程,它不会再次发出相同的连接,直到连接被交回。如果没有交还连接,那么您就有连接泄漏。发生泄漏是因为池没有收到连接用户已完成连接的通知,因此它拒绝分发它。如果对连接是否正在使用有任何疑问,则不提供连接是错误的。

    如果池确实搞砸了并且两次分发相同的连接,则没有锁定可以解决问题,您最终会导致两个线程之一写入错误的架构(除非两者都只是当然,碰巧要求相同的模式)。如果 Hikari 犯了这个错误,它将无法使用。幸运的是,连接池似乎没有问题。

    【讨论】:

    • 感谢您的解释。我今天做了一个测试。我让4个租户连续调用api保存数据(为了触发getConnection(),设置schema)。我将最大池大小设置为 3。事实证明根本没有冲突。数据保存正确,连接正确返回。我认为关键是如果我们可以让 Hikari 正确地回收每个连接,那么就不会发生冲突。我理解正确吗?
    • @Spen1210:对,不应该发生冲突。
    猜你喜欢
    • 2020-01-30
    • 1970-01-01
    • 2022-12-16
    • 1970-01-01
    • 2018-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-19
    相关资源
    最近更新 更多