我遇到了一些長時間運行的存儲過程調用問題,我從DAO調用不返回控件返回到調用DAO的服務。疑難解答Postgres/JPA/Spring與長時間運行的存儲過程
以下是模式: 在我們每年運行一次的AWS SWF工作流中,我有一個服務需要調用5個存儲過程來填充Postgres數據庫中的5個彙總表。所有5個程序都具有相同的格式,非常簡單。他們每個人都從相同的細節表讀取數據,並以不同的方式對數據進行過濾/分組彙總。對於每一個(稱爲同步),該服務:
- 啓動新事務
- 調用一個DAO方法
- 的DAO方法,使用調用PLPGSQL存儲過程JPA的StoredProcedureQuery。
- 當DAO方法完成時,服務會更新單獨的活動表以指示摘要活動已完成。
對於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();
}