2017-03-16 78 views
1

我最近開始使用SOAP webservices,Spring和Hibernate開發一個項目。處理請求後持久化會話對象的數據

我面臨着以下問題:

我們使用SOAP UI發送請求來測試我們的代碼。我已經寫了一個處理賬單的服務。基本上有兩項服務,一項是創建賬單,另一項是賬單處理。

我們有一個表BillTb。在處理賬單之前,我們檢查賬單的狀態。如果賬單狀態爲3(待定),我們處理它。如果不等於3,我們不處理它。賬單處理完畢後,我們將狀態更改爲4(已處理)。

現在,如果該法案狀態爲3,我們做了一些其他表中,最後的條目,狀態變更爲4

如果在處理之間,如果處理失敗,我們需要恢復所有那些條目。所以我們在一個事務中調用這些條目。

DAO層與休眠代碼如下:

import javax.persistence.EntityManager; 
    import javax.persistence.PersistenceContext; 
    import javax.persistence.PersistenceContextType; 
    import javax.persistence.Query; 

     @PersistenceContext(type = PersistenceContextType.EXTENDED) 
      private EntityManager entityManager; 

     public class BillDAOImpl implements BillDao { 

     ... 
     ... 
     ... 

     int pendingStatus = 3; 
     int processedStatus = 4; 

     Session session = null; 

     for(int id: ids){ 

      Bill bill = null; 


     try{ 
      session = entityManager.unwrap(Session.class); 

      bill= entityManager.find(Bill.class, id); 

      session.getTransaction().begin(); 

      if(bill.status() != pendingStatus){ 
      System.out.println("The bill is already processed"); 
     continue; 
      } 
     ... 
... 
bill.setStatus(processedStatus); 
entityManager.persist(bill); 

      session.getTransaction().commit(); 

     } catch(Exception e){ 

     } 

     } 




     } 

現在的問題是,一旦紙幣狀態從3改變爲4,如果我通過燒製更新查詢再次改變狀態,以3在數據庫中,它應該再次工作,但不知何故,它只讀取狀態爲4。

如果我關閉服務器,然後再次執行請求,那麼它適用於相同的條目。

其他與交易有關的參數設置爲:

<property name="hibernate.cache.use_query_cache" value="false" /> 

此外,

<bean id="projectEntityManagerFactory" 
     class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" 
     p:persistenceXmlLocation="classpath*:META-INF/persistence.xml" 
     p:persistenceUnitName="persistenceUnit" p:loadTimeWeaver-ref="loadTimeWeaver" 
     p:jpaVendorAdapter-ref="jpaVendorAdapter" p:jpaDialect-ref="jpaDialect" 
     p:dataSource-ref="datasourceBean"> 
     <property name="jpaProperties"> 
      <props> 
       <prop key="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.BTMTransactionManagerLookup 
       </prop> 
       <prop key="hibernate.transaction.flush_before_completion">false</prop> 
       ... 
       ...    
       <prop key="hibernate.connection.isolation">3</prop> 
       <prop key="hibernate.connection.release_mode">auto</prop> 
      </props> 
     </property> 
    </bean> 

所以在這裏似乎會以某種方式保存該法案的對象,當我直接更新該法案的對象數據庫,它存儲陳舊的數據。那麼在這種情況下應該做些什麼。我應該在方法結束時清除會話嗎?

+0

,這是否狀態改變發生的呢?嘗試添加impl –

+0

我已經更新了代碼。在事務提交之前狀態被更新。 – azaveri7

+0

你爲什麼要搞亂'Entitymanager'和'Session' ......你在不同的對象上重新開始會話。我強烈建議清理你的代碼(使用'EntityManager'並且不要將它解開到'Session'中。 –

回答

0

您應該在事務內部執行查詢,並且記得每次提交事務(如果觸發continue,那是ommited)。

其實我會寫這樣的:

for(int id: ids){ 

     Bill bill = null; 

     Transaction tx = session.getTransaction(); 
     tx.begin(); 

     try{   
      bill= entityManager.find(Bill.class, id); 

      if(bill.status() != pendingStatus){ 
      System.out.println("The bill is already processed"); 
      tx.commit(); 
      continue; 
      } 

      bill.setStatus(processedStatus); 
      entityManager.persist(bill); 

      session.flush(); 
      tx.commit(); 
     }catch(Exception e){ 
      tx.rollback(); 
      throw e; 
     } 
    } 
+0

這似乎是有效的。只有最後一個問題,如果我最終放入它,它總是會嘗試提交如果發生異常,它會去Catch block並且會有回滾,所以我不能在最後提交..所以任何解決方案。 – azaveri7

+0

yes good spot。試試我的更新版本 –

+0

這裏有2個嘗試塊和一個沒有任何finally或catch塊,我認爲它會給編譯錯誤,我嘗試了很多組合,但無法弄清楚在哪裏刷新會話。上面的一個不起作用,因爲如果有一個賬單被成功處理,另一個賬單失敗,它將會因爲事務提交到外面而回滾這兩個賬單對象。 – azaveri7

相關問題