在连续事务发生的方法中EJB3.0事务失败

时间:2014-10-10 07:33:37

标签: ejb-3.0

我正在无状态容器托管bean中的单个方法内处理三个事务.i想要保持三个事务,而如果一个抛出异常,其他两个应该完成它们各自的事务,错误是如果第一个或任何一个抛出异常其他两个要执行请提供一些有用的建议

public void allocateSubjectToStudent(SubjectAllocatedToStudentDto dto)throws Exception {
            logger.info("allocateSubjectToStudent method entry :");


                List<Subject> coreList=dto.getCoreList();
                Iterator<Subject> iterator=coreList.iterator();
                while(iterator.hasNext()){
                    logger.info("inside while :");
                    SubjectAllocatedToStudentBo bo=new SubjectAllocatedToStudentBo();
                    bo.setBacthId(dto.getBacthId());
                    bo.setSemester(dto.getSemester());
                    bo.setStudentId(dto.getStudentId());
                    Subject subject=iterator.next();
                    bo.setSubjectName(subject.getSubjectName());
                    bo.setSubjectType(subject.getAbbreviation());

                    try{
                       manager.persist(bo);
                    }
                    catch(javax.persistence.PersistenceException e){
                        Throwable t = e.getCause();
                        while ((t != null) && !(t instanceof org.hibernate.exception.ConstraintViolationException)) {
                            t = t.getCause();
                        }//while
                        if (t instanceof org.hibernate.exception.ConstraintViolationException) {
                            throw new Exception("Core subject already allocated to student");
                        } //end of if
                    }//end of catch
                }//end of while

                List<Subject> departmentallist=dto.getDepartmentList();
                Iterator<Subject> iterator1=departmentallist.iterator();
                while(iterator1.hasNext()){

                    logger.info("inside while :");
                    SubjectAllocatedToStudentBo bo=new SubjectAllocatedToStudentBo();
                    bo.setBacthId(dto.getBacthId());
                    bo.setSemester(dto.getSemester());
                    bo.setStudentId(dto.getStudentId());
                    Subject subject=iterator1.next();
                    bo.setSubjectName(subject.getSubjectName());
                    bo.setSubjectType(subject.getAbbreviation());
                    try{
                        manager.persist(bo);
                        }
                        catch(javax.persistence.PersistenceException e){

                            Throwable t = e.getCause();
                            while ((t != null) && !(t instanceof org.hibernate.exception.ConstraintViolationException)) {
                                t = t.getCause();
                            }//while
                            if (t instanceof org.hibernate.exception.ConstraintViolationException) {
                                throw new Exception("InterDepartmental subject already allocated to student");
                            } //end of if
                        }//end of catch
                }//end of while

                List<Subject> electiveList=dto.getElectiveList();
                Iterator<Subject> iterator2=electiveList.iterator();
                while(iterator2.hasNext()){

                    logger.info("inside while :");
                    SubjectAllocatedToStudentBo bo=new SubjectAllocatedToStudentBo();
                    bo.setBacthId(dto.getBacthId());
                    bo.setSemester(dto.getSemester());
                    bo.setStudentId(dto.getStudentId());
                    Subject subject=iterator2.next();
                    bo.setSubjectName(subject.getSubjectName());
                    bo.setSubjectType(subject.getAbbreviation());
                    try{
                        manager.persist(bo);
                        }
                        catch(javax.persistence.PersistenceException e){

                            Throwable t = e.getCause();
                            while ((t != null) && !(t instanceof org.hibernate.exception.ConstraintViolationException)) {
                                t = t.getCause();
                            }//while
                            if (t instanceof org.hibernate.exception.ConstraintViolationException) {
                                throw new Exception("Elective subject already allocated to student");
                            } //end of if
                        }//end of catch
                }//end of while


            logger.info("allocateSubjectToStudent method exit :");

        } //end of method

2 个答案:

答案 0 :(得分:1)

在单个方法调用中,只有一个事务处于活动状态。要实现您的目标,您必须在不同的事务中执行三个操作。这需要更多层次的抽象。

public class MyFreshTransaction {

  @TransactionAttribute(REQUIRES_NEW)
  public void updateO() {
   //do something
  }

  @TransactionAttribute(REQUIRES_NEW)
  public void update1() {
   //do something
  }

  @TransactionAttribute(REQUIRES_NEW)
  public void update2() {
   //do something
  }
}

@Stateless
public class MyTransactionProcessor {

  @EJB
  private MyFreshTransaction freshTransaction;

  public void processTransaction() {
    try {
       //The current transaction context will be suspended, and a new one invoked
       //if the new one fails and is rollback, the current one is not affected.
       //you can then handle the exception, by rethrowing the exception,in which case
       //the current transaction will also be rolled back, or continue based on your logic.
       freshTransaction.update0();
    } catch (Exception ex ) {//handle}

    try {
       //The current transaction context will be suspended, and a new one invoked
       //if the new one fails and is rollback, the current one is not affected.
       //you can then handle the exception, by rethrowing the exception,in which case
       //the current transaction will also be rolled back, or continue based on your logic.
       freshTransaction.update1();
    } catch (Exception ex ) {//handle}

    try {
       //The current transaction context will be suspended, and a new one invoked
       //if the new one fails and is rollback, the current one is not affected.
       //you can then handle the exception, by rethrowing the exception,in which case
       //the current transaction will also be rolled back, or continue based on your logic.
       freshTransaction.update2();
    } catch (Exception ex ) {//handle}
  }
}

请注意,如果任何更新事务成功,并且父事务被回滚,它将不会影响'子'事务的状态,因为它们已经被提交及其效果(如果DB效果)也将承诺。

阅读Java EE Transactions Java EE Transactions

答案 1 :(得分:1)

使用TranscationAttributeType REQUIRES_NEW创建三种不同的方法 请在下面找到EJB3 Bean的代码片段

public void doYourWork()
{ 
    a();
    b();
    c();

}
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void a()
{
    try
    {
        //Do the    first transaction here
    }catch(Exception e)
    {

    }
}

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void b()
{
    try
    {
        //Do the    second transaction here
    }catch(Exception e)
    {

    }
}

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void c()
{
    try
    {
        //Do the    third transaction here
    }catch(Exception e)
    {

    }
}