1

我有一个 EJB,其目的是将用户从另一个系统复制到我的系统中,方法是在缺少用户时创建用户,或者更新具有相同 ID 的现有用户。使用了三种方法:

@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_NEWcreateUser()有道理的。换句话说,总共应该有 x 个事务开始,其中 x 是用户数。

问题

EJB 的文档仅涵盖被调用的方法是否应该启动事务,但我应该如何注释调用(“客户端”)方法;timer()正确updateUserDB吗?NOT_SUPPORTS 和 SUPPORTS 导致 ejbTransactionRequiredException在到达em.persist(user)inside时抛出 a createUser(),我认为这是没有意义的,因为createUser()从 SUPPORTS 方法调用时应该允许启动新事务。如果我用 REQUIRED 注释调用方法,则根本不会保留任何用户,那么回滚似乎会影响更大的事务,而不是小的(每个用户)事务。

这三种方法应该怎么注释才能得到想要的效果呢?

编辑
将两个调用方法都设置为Required使JTA不会抛出异常,但由于某种原因,事务每次都会回滚,即使我删除了context.setRollbackOnly().

4

0 回答 0