使用长时间运行的存储过程对Postgres / JPA / Spring进行故障排除

时间:2016-05-31 15:05:12

标签: java spring postgresql jpa amazon-swf

我遇到了几个长时间运行的存储过程调用的问题,我从DAO调用了不会将控制权返回给调用DAO的服务。

以下是这种模式:   在我们每年运行一次的AWS SWF工作流程中,我有一项服务需要调用5个存储过程来填充Postgres数据库中的5个汇总表。所有5个程序都具有相同的格式并且非常简单。它们各自从相同的详细信息表中读取并以不同的方式对数据进行过滤/分组以进行汇总。对于每个(同步调用),服务:

  
      
  1. 开始新的交易      
        
    1. 调用DAO方法
    2.   
    3. DAO方法使用JPA的StoredProcedureQuery调用plpgsql存储过程。
    4.   
    5. 当DAO方法完成时,服务会更新单独的活动表以指示摘要活动已完成。
    6.   
  2.   

对于5个存储过程中的3个,此模式有效。存储过程提交其工作并更新摘要活动。但是,对于2个较长时间运行的存储过程调用(20多分钟),DAO永远不会将控制权返回给服务。存储过程方法确实将其工作提交到数据库,因为这是plpgsql方式,但由于DAO似乎永远不会返回到服务,因此我的活动表未更新以显示该过程已完成。 SWF工作流程也一直在运行,因为服务调用尚未完成。我一夜之间就离开了,并发现虽然存储过程将数据保存到汇总表,但服务/ DAO呼叫仍在12小时后运行。

我不确定我的问题在哪里,所以我很欣赏任何想法。我们的应用程序使用Postgres,Hibernate,JPA和Spring,我们使用BoneCP来设置我们的数据源。我的@Transaction注释中没有设置任何超时,我看到的行为似乎并不表示春天超时。

一些BoneCP设置:

 idleMaxAgeInMinutes=5
  idleConnectionTestPeriodInMinutes=1

所有5个存储过程都使用以下格式:

CREATE OR REPLACE FUNCTION summarize_abc(p_id INTEGER) RETURNS BOOLEAN AS $$
        DECLARE
        BEGIN
         insert into summary_table (a, b, c, d, e, inserted_on)
         select p_id, b, c, d, sum(e) as AMOUNT, CURRENT_TIMESTAMP
         from detail_table s
         where
         s.id = p.id
         group by a, b, c, d;

 RETURN 1;
 END;
 $$ LANGUAGE plpgsql;

DAO方法都是这样的:

 public void summarizeA(int id) {
        ProviderAccess pa = getProviderAccess();
        EntityManager entityManager = getEntityManager();
        StoredProcedureQuery query = entityManager.createStoredProcedureQuery(pa.getSchemaName() +
                ".summarize_abc");
        query.registerStoredProcedureParameter("p_id", Integer.class, ParameterMode.IN);
        query.setParameter("p_id", id);
        query.execute();
    }

1 个答案:

答案 0 :(得分:0)

可能不相关但请注意BoneCP已被弃用。迁移到HikariCP