我有一个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的文档仅涵盖被调用的方法是否应该启动事务,但是我应该如何注释调用(“client”)方法; timer()
和updateUserDB
正确吗? NOT_SUPPORTS和SUPPORTS导致ejb在TransactionRequiredException
内到达em.persist(user)
时抛出createUser()
,我认为这是没有意义的,因为createUser()
应该被允许在调用时启动新事务从支持方法。如果我用REQUIRED注释调用方法,根本没有用户持久化,那么回滚会影响更大的事务,而不是小的(每个用户)事务。
如何对这三种方法进行注释以达到预期效果?
修改
将两个调用方法都设置为Required会使JTA不会抛出异常,但由于某种原因,每次都会回滚事务,即使我删除了context.setRollbackOnly()
。