【问题标题】:Idle In transaction after select statement using Postgres and Hibernate(Grails)使用 Postgres 和 Hibernate(Grails) 的 select 语句后的空闲事务
【发布时间】:2012-01-03 22:15:08
【问题描述】:

我正在使用连接到 Postgres 8.4 的 Grails 1.3.7 我们正在对我们的应用程序进行一些功能测试,但遇到了问题。 几分钟后,我们与数据库的所有连接都处于事务中,请求超时。 我尝试使用来自Ghostwritten Insomnia 的查询来确定发生了什么,我得到的只是一些独占锁和访问共享锁。根据Postgres Docs 的说法,他们一起工作,他们应该没有什么特别之处。好吧,除了它们会一直运行到我重新启动 Tomcat 或终止连接之外,没有什么特别的。 我已启用日志记录并尝试按照 Depesz 在his blog 上的描述分析它们,但我发现没有长时间运行的语句。我能够确定在事务中空闲的连接的最后一条语句,这是一个简单的选择,此外 - 它完成得很好[至少日志是这样说的]。

2012-01-03 21:02:57.397 CET ogsuser@ogs 4294 127.0.0.1(34282) LOG:  duration: 0.111 ms  parse <unnamed>: select questdefin0_.id as id23_0_, questdefin0_.version as version23_0_, questdefin0_.cev_from as cev3_23_0_, questdefin0_.cev_to as cev4_23_0_, questdefin0_.description as descript5_23_0_, questdefin0_.duration as duration23_0_, questdefin0_.level_from as level7_23_0_, questdefin0_.level_to as level8_23_0_, questdefin0_.name as name23_0_, questdefin0_.pack_id as pack10_23_0_, questdefin0_.type as type23_0_, questdefin0_.travel_zone_id as travel13_23_0_, questdefin0_.class as class23_0_ from quest_definition questdefin0_ where questdefin0_.id=$1
2012-01-03 21:02:57.397 CET ogsuser@ogs 4294 127.0.0.1(34282) LOG:  duration: 0.095 ms  bind <unnamed>: select questdefin0_.id as id23_0_, questdefin0_.version as version23_0_, questdefin0_.cev_from as cev3_23_0_, questdefin0_.cev_to as cev4_23_0_, questdefin0_.description as descript5_23_0_, questdefin0_.duration as duration23_0_, questdefin0_.level_from as level7_23_0_, questdefin0_.level_to as level8_23_0_, questdefin0_.name as name23_0_, questdefin0_.pack_id as pack10_23_0_, questdefin0_.type as type23_0_, questdefin0_.travel_zone_id as travel13_23_0_, questdefin0_.class as class23_0_ from quest_definition questdefin0_ where questdefin0_.id=$1
2012-01-03 21:02:57.397 CET ogsuser@ogs 4294 127.0.0.1(34282) DETAIL:  parameters: $1 = '17935'
2012-01-03 21:02:57.397 CET ogsuser@ogs 4294 127.0.0.1(34282) LOG:  execute <unnamed>: select questdefin0_.id as id23_0_, questdefin0_.version as version23_0_, questdefin0_.cev_from as cev3_23_0_, questdefin0_.cev_to as cev4_23_0_, questdefin0_.description as descript5_23_0_, questdefin0_.duration as duration23_0_, questdefin0_.level_from as level7_23_0_, questdefin0_.level_to as level8_23_0_, questdefin0_.name as name23_0_, questdefin0_.pack_id as pack10_23_0_, questdefin0_.type as type23_0_, questdefin0_.travel_zone_id as travel13_23_0_, questdefin0_.class as class23_0_ from quest_definition questdefin0_ where questdefin0_.id=$1
2012-01-03 21:02:57.397 CET ogsuser@ogs 4294 127.0.0.1(34282) DETAIL:  parameters: $1 = '17935'
2012-01-03 21:02:57.397 CET ogsuser@ogs 4294 127.0.0.1(34282) LOG:  duration: 0.052 ms

我浏览了 postgres 的日志文件,寻找 id 为 17935 的其他查询,但没有发现任何可疑之处。并且没有与此查询相同 [或相似] 的时间。

我检查了所有 IDLE In Transaction 连接,发现它们都执行了与最后一条相同的最后一条语句。他们中的大多数有不同的 ID,很少有相同的,但他们在一个非常不同的时刻被执行,所以我怀疑这是根本原因。

我还检查了 Tomcat 上的日志。那里没什么特别的。最后完成的是休眠查询,然后就没有别的了。

我检查了连接池设置,它会在释放后和空闲时检查连接以确保连接正常。

我已经重新启动了 tomcat 并再次运行测试。几分钟后,我在事务中结束了所有连接空闲。这一次不同的查询,再一次我认为没有什么奇怪的。只是一个简单的选择语句。

所以.. 现在是问题部分。 我有什么明显的遗漏吗?我可以应用一些简单的修复,设置或其他东西...... 我不确定我现在应该去哪里解决这个问题,下一步我应该采取什么措施来解决它。

编辑: 把事情说清楚。这是一个部署在 tomcat 上的 grails 应用程序。我们将控制器操作用作“类似 REST”的端点。集成和单元测试运行良好。我们目前正在使用 Soapui 和 5 个线程运行一个简单的场景进行功能测试,模拟用户行为。

【问题讨论】:

  • 您能否将连接池配置为在连接返回池时运行rollback?这应该从 SELECT 语句中结束该隐式事务(这会导致“事务中的空闲”状态)
  • 连接未返回到池中。客户端的请求超时。当我没有更多连接可用时,我完成了测试。
  • 那么你需要在你的测试中明确地编码一个rollback来编辑交易。
  • 我认为我们并不了解对方。这是一个部署在 tomcat 上的 grails 应用程序。我将控制器操作用作 REST 端点。测试是一个soapui loadtest,我有5个线程使用大多数API运行一个场景。没有回滚我可以放在那里。集成和单元测试工作正常。
  • 听起来你需要在 grails 应用程序中解决问题。

标签: java hibernate postgresql grails deadlock


【解决方案1】:

好的.. 所以经过 2 天的痛苦,我们已经设法解决了这个问题。 似乎在使用 HSQLDB 时,我们的设置太有限而无法找到它,这就是为什么它只发生在 Postgres 下。 问题在于春季配置的 bean 池。我不确定它有什么问题,因为它是一个简单的配置,基本上是从 spring 文档中复制和粘贴,但是在更改代码以使对象绕过池之后一切似乎都很好。

【讨论】:

    猜你喜欢
    • 2017-10-03
    • 2013-10-15
    • 1970-01-01
    • 2014-03-23
    • 1970-01-01
    • 2020-03-28
    • 2015-06-22
    • 1970-01-01
    • 2010-12-30
    相关资源
    最近更新 更多