JTA-транзакции из других потоков (ранее JSR-236)

1

Мое приложение Java EE должно иметь фоновый поток, который обновляет состояние БД. Я бы хотел использовать JPA для этой цели. Каковы наилучшие методы для этого? (Наш контейнер EE находится в JSR-236, поэтому ManagedExecutorService не является нашим выбором)


Кстати, я попробовал код ниже, но он не работал - никаких исключений не было, но ничего не было записано в БД. Без фонового потока и с помощью встроенного 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!
  • 0
    Проблема с менеджером сущностей заключается в том, что ему нужна транзакция. И когда вы пишете «em.getTransaction (). Begin ()», он выдает исключение типа «извините, но в режиме JTA возможны только транзакции JTA». А UserTransaction - это JTA-транзакция, поэтому в приведенном выше коде не выдается никаких исключений, но состояние БД в любом случае не меняется.
Показать ещё 4 комментария
Теги:
multithreading
jpa
javabeans
jta

1 ответ

0

Наконец, я нашел простое решение. Он основан на использовании таймеров ejb, как предложил Гимби.

@Singleton
public class IdentityDao{    
    @PersistenceContext
    EntityManager em;

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню