如何检查事务是否标记为回滚?

时间:2017-12-02 19:05:51

标签: java oracle jpa jta transactional

我目前正在编写用于用户管理的Web服务。该项目涉及Oracle DB和XMPP聊天服务器。我正在使用Eclipselink,JPA和JTA进行事务管理。

在注册新用户时,我遇到了一个问题,而我似乎无法用我的JTA知识解决这个问题。

@Transactional(rollbackOn = XMPPException.class)
public User registerUser(User user) throws InvalidArgumentException, NullValueException, ConstraintViolationException, XMPPException {

    if (user == null) {
        throw new NullValueException(new ErrorBuilder(Error.USER_NULL));
    }
    if (user.getEmail() != null && !EmailUtils.isEmailValid(user.getEmail())) {
        throw new InvalidArgumentException(new ErrorBuilder(Error.INVALID_EMAIL).withParams(user.getEmail()));
    }

    Character gender = getGenderOrDefault(user.getGender());
    user.setGender(gender);
    user.setRole(UserRole.USER.getChar());

    em.persist(user);

    //only add xmpp user if registration was successful (if transaction is not marked for rollback)
    if (!em.getTransaction().getRollbackOnly()) {     //throws Exception because I'm using JTA
        xmppService.createUser(user);
    }

    return user;
}

问题是我需要在Oracle DB和XMPP服务器中创建新用户(使用他们的API)。这意味着如果两个单独的创建过程中的一个失败,我也需要回滚另一个。

但是,由于em.persist()不立即抛出异常,而是标记事务以进行回滚,因此继续执行方法并在XMPP服务器上创建用户。

我最初的想法是检查事务是否标记为回滚,但在使用JTA时似乎不能。

所以我的问题是:我应该怎么解决这个问题?我真的不想用2个单独的方法拆分它,如果XMPP失败,只需从Oracle DB中删除用户。

0 个答案:

没有答案