2014-11-20 68 views
0

我有一個存儲函數,它將從數據庫中刪除某些東西,但由於它可能是一個非常長的任務,我想讓一個線程執行此函數,並讓用戶繼續做他在做的事情。創建一個線程來運行Postgres存儲函數

目前,我有以下幾點:

的DAO:

@Override 
    @Transactional 
    public void deleteAll() 
    { 
     Session session = (Session) entityManager.getDelegate(); 
     session.doWork(new Work() 
     { 
      @Override 
      public void execute(Connection connection) throws SQLException 
      { 
       try 
       { 
        // stored function is currently named delete_function() 
        CallableStatement deleteAll= connection.prepareCall("{call delete_function()}"); 
        purgeArchived.execute(); 
        purgeArchived.close(); 
       } 
       catch (SQLException exception) 
       { 
        LOGGER.warn(exception); 
       } 
      } 
     }); 
} 

我怕當我在REST服務調用getDao.deleteAll(),這將是在一個很長的時間,如果工作數據庫有很多東西要刪除。我如何創建一個線程來做同樣的事情?或者這會創建一個線程並執行該功能?

回答

1

是的,你需要爲此創建自己的線程。可能最簡單的做法是將當前deleteAll()方法的全部內容複製到新類的run()方法中,該方法擴展了Thread。假設你叫該類DeleteAllThread,你會然後替換上面

@Override 
public void deleteAll() { 
    new DeleteAllThread().start(); 
} 
+2

小心使用Hibernate時創建線程。由於OP沒有解釋事務管理是如何完成的,所以創建一個Hibernate將執行其方法的線程可以在公共事務管理器的外部,並且該事務在執行後將被回滾。 – 2014-11-20 20:42:04

+0

好點,@LuiggiMendoza。很顯然,我希望這能夠奏效。但我認爲OP的最佳做法是非常仔細地進行測試,無論是在其他交易都承諾並且其他交易失敗的情況下。 – 2014-11-20 20:57:04

+0

你能解釋一下你的評論嗎?執行後回滾?對不起@LuiggiMendoza – PhoonOne 2014-11-20 21:18:59

0

另一種方法是看一看使用ExecutorService你的方法。這可能會讓你的事情變得更清潔。 Here是如何使用ExecutorService的簡單示例。

+0

[This comment](http://stackoverflow.com/questions/27048905/make-a-thread-to-run-a-postgres-stored-function#comment42615854_27049080)也適用於您的答案。 – 2014-11-20 21:03:19

相關問題