2014-11-21 70 views
2

我有一個將調用存儲函數的方法。我希望它異步地完成它的工作。這是我的,但似乎.doWork()永遠不會啓動,因爲當我呼叫getDao.deleteAll(),存儲的功能不會運行。會話異步服務

@Transactional 
    public void delete() 
    { 

     final Session session = (Session) entityManager.getDelegate(); 
     ExecutorService executorService = Executors.newSingleThreadExecutor(); 
     executorService.execute(new Runnable() 
     { 
      @Override 
      public void run() 
      { 
       LOGGER.warn("starting"); 
       session.doWork(new Work() 
       { 
        @Override 
        public void execute(Connection connection) throws SQLException 
        { 
         try 
         { 

          CallableStatement purgeArchived = connection.prepareCall("{call deleteAll()}"); 
          purgeArchived.execute(); 
         } 
         catch (SQLException exception) 
         { 
          LOGGER.warn("Failed to purge archive points. Reason: " + exception); 
         } 
        } 
       }); 
       LOGGER.warn("stopping"); 
      } 
     }); 
     executorService.shutdown(); 
    } 

我看到記錄器已登錄"starting",但它從來沒有得到"stopping"爲什麼會出現這種情況?

+0

嘗試在'run'方法內移動'final Session session =(Session)entityManager.getDelegate();'。 – 2014-11-21 16:53:45

+0

剛剛嘗試過,沒有運氣 – PhoonOne 2014-11-21 17:11:11

+0

嘗試在'executorService.shutdown();'之後使用'while(!executorService.isTerminated()){}'。這將使當前線程等待,直到「ExecutorService」中的線程完成。這是爲了測試目的,因爲如果它在這裏結束,這意味着問題出現在初始化此線程的主線程中。 – 2014-11-21 19:30:46

回答

2

請注意,@Transaction由於事務通常是線程綁定而具有單獨的線程時未實現。

您將需要從run()中的工廠獲取新的entityManager

也去@Async這是更清潔。

同樣知道事務性與@Async

@Async and @Transactional: not working

根據經驗,一般情況下,如果你想使一些工作異步 - 可以把它看成一個獨立的工作單元和一個單獨的事務。

+0

所以目前我的DAO正在擴展一個GenericDAOJpa,它在那裏創建實體管理器。所以你說我應該在run()中創建一個新的? @bhantol – PhoonOne 2014-11-24 14:01:56

+0

添加一個新的entityManager的確奏效!但你能告訴我背後的原因嗎?謝謝@bhantol – PhoonOne 2014-11-24 15:28:33

+0

你還建議使用@Async而不是@Transactional?或者同時使用? – PhoonOne 2014-11-24 15:30:17