2012-12-20 25 views
2

我連接彈簧服務(有問題的),下面的代碼:Spring + Hibernate的保存()不工作

@Async 
    public void performSeismicOperations(Integer sessionUserId, 
      int seismicFileId, String seismicFileName, ShClstr targetCluster, 
      Collection<String> listOperations, String processedFolderName, 
      Map<String, Object[]> args, String userNotes) throws IOException { 

      . 
      . 
      . 
      /*some code*/ 
      . 
      . 
     Date currentDate = new Date(System.currentTimeMillis()); 

      /*IMMEDIATE JOB ENTRY*/  
     log.info("Start : Inserting in sh_job to assure user"); 
     ShJob shJob = new ShJob(user, ClusterConstants.JOB_SUBMITTED, 
       currentDate, null, null, null); 
     shJobDAO.save(shJob); 
     log.info("End : Inserting in sh_job to assure user"); 

     /*some time-consuming operation - 1*/ 

     SeismicFiles processedSeismicFile = new SeismicFiles(user, 
       processedFolderName, 0, HDFSConstants.PROCESSED, currentDate); 
     seismicFilesDAO.persist(processedSeismicFile); 

     /*some time-consuming operation - 2*/ 

     log.info("Start : Updating the Hadoop job id"); 
     shJob.setShjHadoopJobId(hadoopJobId); 
     shJobDAO.attachDirty(shJob); 
     log.info("End : Updating the Hadoop job id"); 

      . 
      . 
      . 
      /*some code*/ 
      . 
      . 

     log.info("Returning from SeismicHadoopServiceImpl.performSeismicOperations()"); 
    } 

DAO代碼

import java.util.List; 

import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory; 
import org.hibernate.LockMode; 
import org.hibernate.Query; 
import org.hibernate.SessionFactory; 
import org.hibernate.criterion.Example; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Repository; 

import com.lnt.seismichadoop.pojo.ShJob; 

@Repository 
public class ShJobDAO { 

    private static final Log log = LogFactory.getLog(ShJobDAO.class); 

    @Autowired 
    private SessionFactory sessionFactory; 

    public void setSessionFactory(SessionFactory sessionFactory) { 
     this.sessionFactory = sessionFactory; 
    } 

    public void persist(ShJob transientInstance) { 
     log.debug("persisting ShJob instance"); 
     try { 
      sessionFactory.getCurrentSession().persist(transientInstance); 
      log.debug("persist successful"); 
     } catch (RuntimeException re) { 
      log.error("persist failed", re); 
      throw re; 
     } 
    } 

    public void save(ShJob transientInstance) { 
     log.debug("SAVING ShJob instance"); 
     try { 
      sessionFactory.getCurrentSession().save(transientInstance); 
      log.debug("save successful"); 
     } catch (RuntimeException re) { 
      log.error("save failed", re); 
      throw re; 
     } 
    } 

    public void attachDirty(ShJob instance) { 
     log.debug("attaching dirty ShJob instance"); 
     try { 
      sessionFactory.getCurrentSession().saveOrUpdate(instance); 
      log.debug("attach successful"); 
     } catch (RuntimeException re) { 
      log.error("attach failed", re); 
      throw re; 
     } 
    } 

    public void attachClean(ShJob instance) { 
     log.debug("attaching clean ShJob instance"); 
     try { 
      sessionFactory.getCurrentSession().lock(instance, LockMode.NONE); 
      log.debug("attach successful"); 
     } catch (RuntimeException re) { 
      log.error("attach failed", re); 
      throw re; 
     } 
    } 

    public void delete(ShJob persistentInstance) { 
     log.debug("deleting ShJob instance"); 
     try { 
      sessionFactory.getCurrentSession().delete(persistentInstance); 
      log.debug("delete successful"); 
     } catch (RuntimeException re) { 
      log.error("delete failed", re); 
      throw re; 
     } 
    } 

    public ShJob merge(ShJob detachedInstance) { 
     log.debug("merging ShJob instance"); 
     try { 
      ShJob result = (ShJob) sessionFactory.getCurrentSession().merge(
        detachedInstance); 
      log.debug("merge successful"); 
      return result; 
     } catch (RuntimeException re) { 
      log.error("merge failed", re); 
      throw re; 
     } 
    } 

    public ShJob findById(java.lang.Integer id) { 
     log.debug("getting ShJob instance with id: " + id); 
     try { 
      ShJob instance = (ShJob) sessionFactory.getCurrentSession().get(
        "com.lnt.seismic.dao.ShJob", id); 
      if (instance == null) { 
       log.debug("get successful, no instance found"); 
      } else { 
       log.debug("get successful, instance found"); 
      } 
      return instance; 
     } catch (RuntimeException re) { 
      log.error("get failed", re); 
      throw re; 
     } 
    } 

    public List findByExample(ShJob instance) { 
     log.debug("finding ShJob instance by example"); 
     try { 
      List results = sessionFactory.getCurrentSession() 
        .createCriteria("com.lnt.seismic.dao.ShJob") 
        .add(Example.create(instance)).list(); 
      log.debug("find by example successful, result size: " 
        + results.size()); 
      return results; 
     } catch (RuntimeException re) { 
      log.error("find by example failed", re); 
      throw re; 
     } 
    } 

    public List<ShJob> findAll() { 
     log.debug("finding JobStatus instance by findAll"); 
     try { 
      Query query = sessionFactory.getCurrentSession().createQuery(
        "from ShJob"); 
      List<ShJob> results = query.list(); 
      log.debug("find by findAll successful, result size: " 
        + results.size()); 
      return results; 
     } catch (RuntimeException re) { 
      log.error("find by example failed", re); 
      throw re; 
     } 
    } 
} 

我的要求是,一個項目必須去成作業表,一旦處理開始(/IMMEDIATE JOB ENTRY/中的代碼)。/一些耗時的操作完成後 - 2 /,我將更新同一條目(用適當的狀態)。 雖然我讀保存(之差),堅持(),我保存()仍然推遲插入,直到/ 一些費時的操作 - 2 /這反過來,反映了一個條目前端很晚。

請指引我到哪裏,我做一個大錯。

1日編輯

在我的情況下,用戶提交其涉及到標@Async上述服務方法的操作請求 - 用戶必須看到一個頁面,他的要求顯示「提交」,而運營方式仍在繼續。在這種情況下,我應該使用session.flush()還是需要進行任何代碼更改?

+0

您是否嘗試在保存後刷新更改 –

回答

3

savepersist,並且一般情況下,對持久實體進行的每項操作都將推遲到真正必要時,以避免不必要的往返數據庫。

您可以讓Hibernate使用session.flush()將每個掛起的更改寫入數據庫,但這不會使該實體可用於前端,因爲ront-end不使用相同的事務來讀取數據而不是長期運作並堅持實體的人。

而且由於事務處於隔離狀態(大多數情況下默認隔離是READ_COMMITTED),事務在其他事務提交到數據庫之前不會看到其他事務寫入的任何內容。

如果你想瑟插入的實體,立即將其保存在單獨的事務從長期運行操作的其餘部分,或更改隔離級別READ_UNCOMMITTED。

+0

在我的情況中,用戶提交了一個操作請求,該請求涉及上述服務方法,標記爲@Async - 用戶必須看到一個頁面,其請求顯示'已提交'而服務方法中的操作仍在進行。 在這種情況下,我將使用調用Session.flush()或者我需要更改代碼? –

+0

正如我說:你需要有一個單獨的事務剛剛保存工作,並繼續長時間操作之前提交。 Session.flush()將無濟於事。 –

+0

u能提供的示例代碼,我怎麼也得做(單獨交易)? –

相關問題