2014-10-10 32 views
0

我正在處理無狀態容器託管bean中的單個方法內的三個事務。如果一個拋出異常,另一個應該完成它們各自的事務,錯誤是,如果第一個或任何一個被拋出的異常其他兩個是在執行請給一些有益的建議EJB3.0事務在發生連續事務的方法內失敗

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 

回答

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

注意,如果任何更新事務的成功,與父事務回滾,也不會影響到「子」事務的狀態,因爲他們已經承諾及影響(如果數據庫效應)也將被提交。

閱讀上的Java EE交易Java EE Transactions

+0

我不想創建其他類。我嘗試通過創建內部類來實現,但不工作 – Shardendu 2014-10-14 12:03:57

+0

EJB將能夠管理事務的唯一方法是管理bean。你也可以注入到自己的bean(我沒有測試過這個,但我想它應該工作) – maress 2014-10-14 14:34:23

1

創建三個不同的方法,所有TranscationAttributeType REQUIRES_NEW 請看以下代碼片段EJB3豆

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) 
    { 

    } 
} 
+0

我創建了三種方法,但它不工作,你可以告訴我你的代碼你要如何實現它 – Shardendu 2014-10-14 12:03:25

+0

裏面趕上我拋出一個例外,我認爲由於其他兩個交易沒有得到執行我想拋出不同的信息在不同的捕獲 – Shardendu 2014-10-15 06:00:26

+0

如果您使用REUIRES_NEW然後其他兩個交易將不會中斷 – 2014-10-16 05:09:48