Shardendu
Shardendu

Reputation: 3590

EJB3.0 transaction fail inside a method in successive transaction taking place

I am processing three transaction inside a single method in stateless container managed bean .i want to persist three transaction while if one throws exception other two should complete their respective transaction ,error is that if first or any one is throwing exception other two are to executing please give some helpful suggestion

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

Upvotes: 0

Views: 137

Answers (2)

maress
maress

Reputation: 3533

Within a single method invocation there is only a single transaction active. To achieve what you want, you must perform the three operations in different transactions. This would require one more level of abstracttion.

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}
  }
}

Note that if any of the update transaction was successful, and the the parent transaction is rolled back, it will not affect the status of the 'child' transactions, as they had already been committed and their effects (if DB effects) will be committed too.

Read on Java EE Transactions Java EE Transactions

Upvotes: 1

Nishant Modi
Nishant Modi

Reputation: 679

create three different method all with TranscationAttributeType REQUIRES_NEW Please find below code snippet for 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)
    {

    }
}

Upvotes: 1

Related Questions