2014-09-03 93 views
1

我有一個彈簧集成int-jpa:使用jpa查詢檢索出站網關。 插入花費的時間不到一秒鐘,讀取存在的行花費的時間不到一秒鐘。 但是,當我搜索數據庫中不存在的值時,或者如果我搜索空的數據庫,查詢需要一分多鐘才能完成,這會導致我的應用程序中出現超時。 我已經嘗試了一個本地查詢以及相同的結果發生。我在pgadmin中運行了本機查詢,並花了17毫秒才完成。JPA空數據庫性能

任何人都可以對我這個現象有任何解釋嗎?集成流程始於一個網關,每個crud操作都映射到特定的通道。服務接口接收實體並返回一個Message類型。

<int-jpa:retrieving-outbound-gateway id="select-in" 
    entity-manager-factory="entityManagerFactory" request-channel="eselect-in-channel" 
    jpa-query="${db.query.select.in}" expect-single-result="false" > 
    <int-jpa:parameter expression="payload.myKey" name="myKey"/> 
    <int-jpa:parameter expression="payload.myIds" name="myIds"/> 
</int-jpa:retrieving-outbound-gateway> 

這裏是JPA查詢:

db.query.select=SELECT x FROM MyEntity x WHERE x.myId IN :myIds AND x.myKey = :myKey 

- 編輯 -

的應用還處於發展,一切都在本地主機上運行。 到目前爲止我所做的測試中,數據庫大小還沒有超過5或10條記錄。 整個數據庫由一個myId和myKey作爲組合PK的表組成。 表的其餘部分由時間戳表示的插入時間和varchar類型

的type_description的 - 編輯 -

看AbstractReplyProducingMessageHandler的處理郵件的內部方法後的空,因此沒有任何結果發佈到輸出通道。在我的情況下,沒有輸出/回覆通道,所以空的列表應該返回給調用者,這是我的網關。但由於記錄不存在,結果爲空,結果處理程序永遠不會被調用,調用程序也不會被通知並最終超時。

if (result != null) { 
     MessageHeaders requestHeaders = message.getHeaders(); 
     this.handleResult(result, requestHeaders); 
    } 
    else if (this.requiresReply) { 
     throw new ReplyRequiredException(message, "No reply produced by handler '" + 
       this.getComponentName() + "', and its 'requiresReply' property is set to true."); 
    } 
    else if (logger.isDebugEnabled()) { 
     logger.debug("handler '" + this + "' produced no reply for request Message: " + message); 
    } 

我的印象是一個空表本來是要返回時,沒有結果發現 http://forum.spring.io/forum/spring-projects/integration/124469-jpa-retrieving-outbound-gateway-produced-no-reply-when-zero-entities-in-database

+0

您能否提供更多信息。例如,你在db中有多少條記錄,索引是什麼。應用程序服務器是否與數據庫服務器分開(或它們位於同一服務器中)等等。 – pms 2014-09-03 15:34:37

+0

我建議你在「掛起」時使用線程轉儲(jstack或visualVM)。 – 2014-09-03 16:50:24

+0

嗨@GaryRussell你可以評論下面的答案嗎?我真的很想得到你的意見。 – peekay 2014-09-15 21:02:28

回答

1

好了,所以這是我的HACK,使這項工作:

<gateway id="persistence-gateway" 
    service-interface="com.service.JPAService" 
    default-request-timeout="${default.request.timeout}" default-reply-timeout="${default.reply.timeout}" 
    error-channel="jpaErrorChannel"> 
    <method name="executeSelectIn" request-channel="select-in-channel"/> 
</gateway> 

<channel id="select-in-channel" /> 

<int-jpa:retrieving-outbound-gateway id="select-in" 
    entity-manager-factory="entityManagerFactory" request-channel="select-in-channel" 
    jpa-query="${db.query.select.in}" expect-single-result="false" > 
    <int-jpa:parameter expression="payload.myKey" name="myKey"/> 
    <int-jpa:parameter expression="payload.myIds" name="myIds"/> 
</int-jpa:retrieving-outbound-gateway> 

<!-- Error preprocessing --> 
<channel id="jpaErrorChannel" /> 

<payload-type-router id="jpaErrorRouter" 
    input-channel="jpaErrorChannel" 
    default-output-channel="jpaErrorProcessorChannel"> 
    <mapping type="org.springframework.integration.handler.ReplyRequiredException" channel="jpaErrorPassthroughChannel"/> 
</payload-type-router> 

<channel id="jpaErrorPassthroughChannel" /> 

<transformer id="jpaErrorPassthroughTransformer" 
    input-channel="jpaErrorPassthroughChannel" 
    expression="T(java.util.Collections).emptyList()"/> 

這裏是jpa查詢:

db.query.select=SELECT x FROM MyEntity x WHERE x.myId IN :myIds AND x.myKey = :myKey 

我不喜歡不喜歡它,但現在它工作。我認爲這是春天AbstractReplyProducingMessageHandler中的一個bug,但我想知道Spring Guru的想法。

+0

更簡單的解決方法是:https://jira.spring.io/browse/INT-3333。因爲你還沒有修好。我們很快可能會解決它。 – 2014-09-16 09:04:13

+0

謝謝@Artem - 另一個簡單的工作(在這種情況下)是在網關上設置default-reply-timeout =「0」,並將null視爲一個空列表。 – 2014-09-16 09:14:37