2014-08-28 17 views
1

我的Java EE應用程序應該有一個後臺線程,它會更新數據庫狀態。我想用JPA來達到這個目的。有什麼最佳做法來做到這一點? (我們的EE容器之前JSR-236,所以ManagedExecutorService不是我們的選擇)來自其他線程的JTA事務(以前的JSR-236)


通過我試過的代碼波紋管的方式,但它沒有工作 - 沒有任何異常被拋出,但沒有被保存到數據庫。沒有後臺線程和使用注入EntityManager的一切保存:

@Singleton 
public class IdentityDao{ 

    @PersistenceUnit(unitName = "routing") 
    private EntityManagerFactory emf; 
    @Resource 
    private UserTransaction utx; 

    @PostConstruct 
    protected void startConverter() { 
     new Converter(); 
    } 

    private class Converter implements Runnable { 
     private Converter() { 
      ScheduledExecutorService scheduler = ThreadUtils.newSingleThreadScheduledExecutor("test", true); 
      scheduler.scheduleAtFixedRate(this, 5, 5, TimeUnit.SECONDS); 
     } 

     @Override 
     public void run() { 
      EntityManager em = emf.createEntityManager(); 
      try { 
       utx.begin();      
       em.persist(new PersonEntity("123")); 
       utx.commit(); 
      } catch (Exception e) { 
       try { 
        e.printStackTrace(); 
        utx.rollback(); 
       } catch (Exception exc) { 
       } 
      } finally { 
       em.close(); 
      } 
     } 
    } 
} 
+1

如果你有一個EntityManager,那你爲什麼使用UserTransaction?使用EntityManager! – Gimby 2014-08-28 13:34:28

+0

實體管理器的問題在於它需要事務。當你寫「em.getTransaction()。begin()」時,它會拋出異常,如「抱歉,但在JTA模式下只有JTA事務是可能的」。而UserTransaction是一個JTA事務,所以在上面的代碼中沒有拋出異常,但是DB狀態不會改變。 – user3231055 2014-08-29 07:12:59

+0

我不知道ThreadUtils是做什麼的。它使用的是JEE ManagedScheduledExecutorService還是標準的JSE ScheduledExecutorService?您應該在JEE環境中使用前者,以便實際進行容器管理。 http://stackoverflow.com/questions/25237111/start-stop-a-scheduledexecutorservice-in-jee-environment-using-servlet – Gimby 2014-08-29 07:25:30

回答

0

最後我找到了簡單的解決方案。正如Gimby所建議的那樣,它基於使用ejb計時器。

@Singleton 
public class IdentityDao{  
    @PersistenceContext 
    EntityManager em; 

    @Schedule(hour = "*", minute = "*", second = "*/10") 
    public void every10Sec() { 
     em.persist(new PersonEntity("123")); 
    } 
}