@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) 不起作用

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) doesn't work

我需要在 glassfish3 上使用 JPA 2.0 和 EJB3.0 删除忽略任何完整性约束的员工列表(即成功删除与任何其他人不相关的实体或跳过与其他人相关的实体) .0:

我迭代列表并在 try/catch 的 require_new 事务中调用实体管理器,我希望这将在大事务中打开小嵌套事务,我使用 em.flush() 强制更新。

但在相关实体的迭代中它抛出;

Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.4.2.v20130514-5956486): org.eclipse.persistence.exceptions.DatabaseException Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails

并继续下一个员工,但在提交大事务时它回滚并抛出相同的异常!

我希望 throw/catch 新小事务中的异常并提交列表其余部分成功删除的实体...

我有什么想念的吗?

编辑:

这是一些代码,Facade中调用实体管理器移除bean的代码,我用required-new注释了函数:

 public void deleteEmployeeData(Set<Employees> deleted) throws DatabaseException {

        Iterator itr;
        Employees emp;


        //delete unused recordes 
        try {

            itr = deleted.iterator();

            while (itr.hasNext()) {
                emp = (Employees) itr.next();
                deleteEmployee(emp);                
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println("DONE");
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    private void deleteEmployee(Employees emp){
        try {
                    this.remove(emp);
                } catch (Exception ex) {
                    System.out.println(ex.getMessage());
                }

    }

你的问题似乎是你想在 try catch 中以编程方式捕获事务错误,但你的事务传播是声明性的(使用注释),它通常会创建代理堆栈并通过它们透明地处理事务失败。您需要使用编程事务并将其包装在您的异常处理代码中。

deleteEmployee 方法未包装到新事务中,因为您正在引用 this 上的方法。您可以做的是注入对外观本身的引用,然后对其调用 deleteEmployee 方法(应该是 public)。

大致是这样的:

@Stateless
public class MyFacade {
    @EJB
    private MyFacade self;

   public void deleteEmployeeData(Set<Employees> deleted) throws DatabaseException {
     ...
     try {
       self.deleteEmployee(emp);
     } catch (Exception ex) {
       // ...
     }
     ...
   }

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public void deleteEmployee(Employees emp) {
      this.remove(emp);
    }

}

要调用本地方法并用新事务包装它,

@Stateless
public class UserFacade implements UserFacadeLocal {
@Resource
private SessionContext context;

@Override
@TransactionAttribute(TransactionAttributeType.REQUIRED)
private void create(User user) {
        System.out.println("Users Count: "+count()); //invocation#1
        System.out.println("Users Count Through Context: "+context.getBusinessObject(UserFacadeLocal.class).count()); //invocation#2
    }

@Override
@TransactionAttribute(TransactionAttributeType.NEVER)
    public int count() {
        return ((Long) q.getSingleResult()).intValue();
    }
}

EJB Transactions in local method-calls