2015-10-02 52 views
0

我在我的JavaEE項目上使用Spring + Hibernate。使用Spring + Hibernate進行連接重置

在這個項目中,用戶可以上傳一個我應該導入到我的數據庫的XLS文件。在導入之前,我必須驗證此文件,以檢查數據庫中其他實體的完整性。所以我有更多或更少的以下內容:

// The importer 
@Component("importer") 
public class Importer { 

    @Autowired 
    FirstDAO firstDao; 

    @Autowired 
    SecondDAO secondDao; 

    // Read the file and open it (65.000 lines for example) 

    public void validate() { 

     foreach line in the file { 
      firstDAO.has(line[col1]); 
      secondDao.has(line[col2]); 
     } 

     // It stores the valid objects in a List and persist them at the end 

    } 
} 

// The DAO 
@Repository 
public class FirstDao { 

    @PersistenceContext 
    protected EntityManager entityManager; 

    @Transactional(propagation = Propagation.NOT_SUPPORTED) 
    public boolean has(String name) { 

     List<Object> result = entityManager.createQuery(from FIRST_TABLE where name = :name) 
     .setParameter("name", name) 
     .getResultList(); 

     if (result.size > 0) return true; 
     else return false; 
    } 

} 

// The PersistenceContext/Hibernate configuration 

<!-- Data Source --> 
<jee:jndi-lookup id="myDS" jndi-name="jdbc/my-DS" cache="true" proxy-interface="javax.sql.DataSource" /> 

<!-- Entity Manager --> 
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property value="classpath:META-INF/my_persistence.xml" name="persistenceXmlLocation"/> 
    <property name="dataSource" ref="myDS"/> 
    <property name="persistenceUnitName" value="myPersistenceUnit" /> 
    <!-- 
    <property name="loadTimeWeaver"> 
     <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/> 
    </property> 
    --> 
    <property name="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
      <property name="database" value="ORACLE" /> 
      <property name="showSql" value="false" /> 
     </bean> 
    </property> 
</bean> 

登錄我已經注意到了應用程序後:

  • 對於每個查詢(對我的DAO方法)打開一個連接,並與我的數據庫已經關閉。
  • 服務器上的內存被淹沒(可能是內存泄漏)。
  • 經過大量的打開和關閉連接後,我從數據庫重置了連接。不知道爲什麼。如果我仍然繼續請求連接,數據源將被暫停。

我已閱讀出頭約entityManager但我仍然不,知道如果我這樣做是正確的這樣:

  • 那麼,是否可以在執行驗證for循環呀? (每個項目一個連接,意味着在65000行文件中打開和關閉130.000個連接)
  • 我已閱讀了有關entityManager的Stateless Persistence Context。我懷疑內存泄漏可能在那裏。也許Hibernate正在關閉PersistenceContext中的很多對象。如何讓Entity Manager在驗證時不緩存這些人?

在此先感謝。

+0

你的問題聽起來像一個問題的列表。但是關於連接到文件的每一行的數據庫,這會使系統的性能下降很多。你不能遍歷整個文件,將它加載到內存中,然後運行單個select語句來檢索需要與加載文件進行比較的db數據?將所有數據加載到內存中,然後立即進行驗證。您可能需要先解決內存泄漏問題。 – wdoering

回答

0

首先,除非你有非常好的理由,否則你不應該一直這麼做。即使數據量大於你的內存,你應該一次做1000行或類似的東西,但絕對不是一個一個。 因爲數據庫使用最重要的優化之一是減少了數據庫命中次數。

其次,你不應該檢索數據只是爲了檢查它是否存在。 您應該使用基本的「select count」查詢。通過這種方式,你將擺脫所有的東西,比如使用IO來讀取數據並通過網絡將數據檢索到服務器,並花費內存來獲取該列表中的對象數量。

如果您將使用我的第一條建議,並且一次只檢查1000個記錄的現有記錄,則可以只選擇名稱而不是所有行。

順便說一句,據我所見,你正在使用的數據源,如果正確配置像最大連接數等你不應該擔心數據庫連接的數量。

相關問題