Quartz 2 + Hibernate 4 多租户不稳定行为

Posted

技术标签:

【中文标题】Quartz 2 + Hibernate 4 多租户不稳定行为【英文标题】:Quartz 2 + Hibernate 4 multitenant erratic behaviour 【发布时间】:2014-07-16 11:29:51 【问题描述】:

我目前正在实现一个多租户 Web 应用程序,其中一些后台任务由计时器或 Quartz 作业运行。

为此,我使用Hibernate 4 multitenant features 并使用基于模式的策略。通过在我的 MultiTenantConnectionProvider 实现中调用以下内容来进行模式切换:

connection.createStatement().execute("SET search_path TO '" + tenantIdentifier + "'");

该问题仅在 Quartz Job 执行中出现,TimerTask 下的相同代码可以正常工作。出于许多充分的理由,我想使用 Quartz over Timer(持久性、错误处理、触发设施)。

当一个作业遍历租户列表并在新事务中运行查询时,查询有时会为每个租户返回正确的值,有时会返回另一个租户的值。

我在 Hibernate 和 Spring 中启用了 TRACE 日志级别,我可以看到为每个租户打开的会话。

我还跟踪了数据库日志中执行的语句,显然出现了问题。这是一个好的执行:

SET search_path TO public

SET search_path TO 'tenantA'
BEGIN
/* criteria query */
select * from TABLE1_ this_ where this_.published_=
 = 't'
/* load one-to-many */
select * from TABLE2_ where id_table1_=
 = '1234'
COMMIT

SET search_path TO public

SET search_path TO 'tenantB'
BEGIN
/* criteria query */
select * from TABLE1_ this_ where this_.published_=
 = 't'
/* load one-to-many */
select * from TABLE2_ where id_table1_=
 = '5678'
/* load collection */
select * from TABLE3_  where id_table2_=
 = '9876'
COMMIT

SET search_path TO public

当问题出现时,执行相同的操作:

SET search_path TO public

SET search_path TO 'tenantA'
BEGIN
/* criteria query */
select * from TABLE1_ this_ where this_.published_=
 = 't'
/* load one-to-many */
select * from TABLE2_ where id_table1_=
 = '5678'
/* load collection */
select * from TABLE3_  where id_table2_=
 = '9876'
COMMIT

SET search_path TO public

SET search_path TO 'tenantB'
BEGIN
/* criteria query */
    select * from TABLE1_ this_ where this_.published_=
 = 't'
/* load one-to-many */
select * from TABLE2_ where id_table1_=
 = '1234'
COMMIT

SET search_path TO public

在这种情况下,查询被交换,在其他情况下对两个租户执行相同的操作。在分析数据库日志时,似乎 sessionid 对于相同的查询是相同的。

三重检查我自己,我在事务中打印SHOW search_path; 的结果,它总是返回正确的路径。

同样,当代码在 TimerTask 中运行时,此行为不会出现。

有什么想法吗?我意识到这是一个复杂的问题,如果你没有亲身经历过,很难理解。但这就是我所希望的,有人已经经历过同样的事情,并且可以对此事有所了解。 如果需要,我可以提供更多信息,但目前我认为足以说明问题。

环境:

Java 7 春季 3.2.6 休眠 4.2.12 石英 2.2.1 PostgreSQL 9.1

【问题讨论】:

【参考方案1】:

找到好的解决方案。不是休眠多租户问题。我尝试实现自己的数据源代理机制,但问题仍然存在。也没有 Quartz 问题,即使是我之前报告的在这种情况下发生的问题,也是众多问题之一。在完全禁用 Quartz 后,其他问题也会以同样不稳定和随机的方式出现。

解决方案:使用 PostgresSQL 9.3。

为什么?不知道。花了几分钟阅读更新日志,但经过几天的努力,我有很多东西要赶上。如果有人有线索,请分享。

【讨论】:

以上是关于Quartz 2 + Hibernate 4 多租户不稳定行为的主要内容,如果未能解决你的问题,请参考以下文章

如何基于 K8S 多租能力构建 Serverless Container

华为云企业级Redis:集群搭载多DB,多租隔离更降本

spring 4 quartz 2.x动态配置triggers

Quartz学习(转)

quartz学习笔记

quartz学习笔记