2014-11-20 35 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

相关问题