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