多租户情况下 getConnection() 可能发生并发冲突
Possible concurrency conflict in getConnection() under multitenancy situation
我正在实施基于数据库模式的多租户策略。我将 PostgreSQL 用于数据库,将 HikariCP 用于池,它是一个 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 个不同的连接,并且模式集不会发生冲突。但这是真实的情况吗?我们这里需要 read/write 锁吗?先谢谢了。
连接池会跟踪它检出的连接;一旦一个连接被移交给一个线程,它就不会再次发出相同的连接,直到连接被移交回来。如果未交回连接,则说明连接泄漏。发生泄漏是因为池没有收到连接用户已完成连接的通知,因此它拒绝分发。如果对连接是否正在使用有任何疑问,它会在不分发连接方面出错。
如果池确实搞砸了并且两次发出相同的连接没有锁定你可以这样做会解决问题,你最终会导致两个线程之一写入错误的模式(除非当然,两者都碰巧要求相同的模式)。如果 Hikari 犯了这个错误,它将无法使用。幸运的是,连接池似乎没有问题。
我正在实施基于数据库模式的多租户策略。我将 PostgreSQL 用于数据库,将 HikariCP 用于池,它是一个 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 个不同的连接,并且模式集不会发生冲突。但这是真实的情况吗?我们这里需要 read/write 锁吗?先谢谢了。
连接池会跟踪它检出的连接;一旦一个连接被移交给一个线程,它就不会再次发出相同的连接,直到连接被移交回来。如果未交回连接,则说明连接泄漏。发生泄漏是因为池没有收到连接用户已完成连接的通知,因此它拒绝分发。如果对连接是否正在使用有任何疑问,它会在不分发连接方面出错。
如果池确实搞砸了并且两次发出相同的连接没有锁定你可以这样做会解决问题,你最终会导致两个线程之一写入错误的模式(除非当然,两者都碰巧要求相同的模式)。如果 Hikari 犯了这个错误,它将无法使用。幸运的是,连接池似乎没有问题。