EJB Транзакции проблемы - PullRequest
1 голос
/ 24 мая 2011

У меня есть EJB, целью которого является копирование пользователей из другой системы в мою, путем создания пользователя в случае его отсутствия или обновления существующего пользователя с тем же идентификатором. Используются три метода:

@Schedule(second = "0", minute = "0", hour = "0", persistent = false)
@TransactionAttribute(TransactionAttributeType.SUPPORTS)
public void timer(){
    updateUserDB();
    // Some other stuff
}

@TransactionAttribute(TransactionAttributeType.SUPPORTS)
public void updateUserDB(boolean delta) {
    // Find users in external system
    for(every user in the external system) {
        createUser(externalUser);
}

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
private void createUser(User externalUser) {
    try{
        em.persist(user);
        em.flush();
        return;
    }catch(Exception e){} // Logs
    em.clear(); // Make sure the user is removed from the persistence context (or it will try to add it again if an error occured at the next flush
    context.setRollbackOnly(); // Rollback if error occured

Сценарий, который я ищу, состоит в том, чтобы сохранить всех пользователей, если произошла ошибка, я хочу зарегистрировать это и откатить это единственное сохранение, а затем продолжить с остальными пользователями. Так что REQUIRES_NEW на createUser() имеет смысл. Другими словами, в общей сложности должно быть х количество транзакций, где х - количество пользователей.

Проблема

Документация по EJB охватывает только то, должен ли вызываемый метод начинать транзакцию или нет, но как я должен аннотировать вызывающие ("клиентские") методы; timer() и updateUserDB правильно? NOT_SUPPORTS и SUPPORTS заставляют ejb выдавать TransactionRequiredException при достижении em.persist(user) внутри createUser(), что, я думаю, не имеет смысла, поскольку createUser() должно быть разрешено начинать новую транзакцию при вызове из метода SUPPORTS. Если я аннотирую вызывающие методы с помощью REQUIRED, пользователи вообще не сохраняются, похоже, что откат влияет на большую транзакцию, а не на маленькую (на пользователя) транзакцию.

Как аннотировать эти три метода, чтобы получить желаемый эффект?

Редактировать
Если для обоих методов вызова установлено значение Required, JTA не выдает исключение, но транзакция по какой-то причине откатывается каждый раз, даже если я удаляю context.setRollbackOnly().

...