我有一个 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_NEW
是createUser()
有道理的。换句话说,总共应该有 x 个事务开始,其中 x 是用户数。
问题
EJB 的文档仅涵盖被调用的方法是否应该启动事务,但我应该如何注释调用(“客户端”)方法;timer()
正确updateUserDB
吗?NOT_SUPPORTS 和 SUPPORTS 导致 ejbTransactionRequiredException
在到达em.persist(user)
inside时抛出 a createUser()
,我认为这是没有意义的,因为createUser()
从 SUPPORTS 方法调用时应该允许启动新事务。如果我用 REQUIRED 注释调用方法,则根本不会保留任何用户,那么回滚似乎会影响更大的事务,而不是小的(每个用户)事务。
这三种方法应该怎么注释才能得到想要的效果呢?
编辑
将两个调用方法都设置为Required使JTA不会抛出异常,但由于某种原因,事务每次都会回滚,即使我删除了context.setRollbackOnly()
.