Java 来自其他线程的JTA事务(之前的JSR-236)

Java 来自其他线程的JTA事务(之前的JSR-236),java,multithreading,jpa,javabeans,jta,Java,Multithreading,Jpa,Javabeans,Jta,我的JavaEE应用程序应该有一个后台线程,用于更新DB状态。为此,我想使用JPA。做这件事的最佳实践是什么?我们的EE容器是之前的JSR-236,所以ManagedExecutorService不是我们的选择 顺便说一句,我尝试了下面的代码,但它没有工作-没有抛出异常,但没有保存到DB中。没有后台线程并使用注入的EntityManager保存所有内容: @Singleton public class IdentityDao{ @PersistenceUnit(unitName = "

我的JavaEE应用程序应该有一个后台线程,用于更新DB状态。为此,我想使用JPA。做这件事的最佳实践是什么?我们的EE容器是之前的JSR-236,所以ManagedExecutorService不是我们的选择

顺便说一句,我尝试了下面的代码,但它没有工作-没有抛出异常,但没有保存到DB中。没有后台线程并使用注入的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();
            }
        }
    }
}

最后我找到了简单的解决办法。正如Gimby所建议的,它基于ejb定时器的使用

@Singleton
public class IdentityDao{    
    @PersistenceContext
    EntityManager em;

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

如果您有EntityManager,那么为什么要使用UserTransaction?使用EntityManager!实体管理器的问题在于它需要事务。当您编写em.getTransaction.begin时,它会抛出类似sorry的异常,但在JTA模式下,只有JTA事务是可能的。UserTransaction是一个JTA事务,所以在上面的代码中没有抛出异常,但是DB状态无论如何都不会改变。我不知道ThreadUtils做了什么。它是使用JEE ManagedScheduledExecutorService还是标准的JSE ScheduledExecutorService?您应该在JEE环境中使用前者,因此它实际上是容器管理的。似乎我们的web容器太旧,无法提供JSR-236功能,所以我们需要一些旧的解决方案。我同意,您应该研究一下。可能是经典的EJB计时器服务。PS:您应该在实际问题中添加一些重要的细节,比如在遗留技术上运行。