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

时间:2014-05-27 13:51:52

标签: spring hibernate postgresql quartz-scheduler multi-tenant

我目前正在实施多租户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
  • Spring 3.2.6
  • Hibernate 4.2.12
  • Quartz 2.2.1
  • PostgreSQL 9.1

1 个答案:

答案 0 :(得分:0)

好的解决方案找到了。不是Hibernate Multi Tenancy问题。我尝试实现自己的数据源代理机制,问题仍然存在。也没有石英问题,即使是我之前报告的在这种情况下发生的问题,也是众多问题之一。在完全禁用Quartz之后,其他问题以同样的不规则和随机方式上升。

  

解决方案:使用PostgresSQL 9.3。

为什么呢?不知道。阅读更改日志已经失去了一些时间,但经过几天的努力,我有很多要赶上来。如果有人有线索,请分享。