Search code examples
javajakarta-eerollback

Rollback a transaction in a function calling another function


I want to rollback a transaction in function say xyz()

This xyz calls another function say abc() within it that has its own transaction tx. If due to an exception Abc() rolls back its transaction,hence transaction in xyz() should also get rolled back. How can i rollback transaction in xyz() ?

This is my code.

public String execute() throws Exception {
        //  viewReadOnly();
        Session sf=null;
         Transaction tx=null;

        try {
              sf = HibernateUtil.getSessionFactory().getCurrentSession();
              tx = sf.getTransaction();

             tx.begin();

            //sosFile.setCmaId(1);
            //sosFile.setSosFileId(1);
            //sosFile.setHeadImage(new ImageService().readImageOldWay(headFile));
            //sosFile.setFootImage(new ImageService().readImageOldWay(footFile));

            //if(new ImageService().readImageOldWay(headFile) != null)

           System.out.println("FLAG="+flag);

          if(headFile!=null)
         {

           for (int i = 0; i < headFile.length; i++) {

            if (headFile != null) {
                sosOrder = new SOSCustomerOrderFile();
                sosOrder.setCmaId(cmaId);



                sosOrder.setFileData(new ImageService().readImageOldWay(headFile[i]));
                sosOrder.setFileName(new File(sosorderfilename[i]).getName());
                sosOrder.setSosStage(flag);

                sf.saveOrUpdate(sosOrder);
                }

           }
        }  
          if(footFile!=null)
          {

           for (int i = 0; i < footFile.length; i++) {

            if (footFile != null) {
                sosCheque.setCmaId(cmaId);
                sosCheque.setFileData(new ImageService().readImageOldWay(footFile[i]));
                sosCheque.setFileName(new File(soschequefilename[i]).getName());
                sosCheque.setSosStage(flag);

                sf.saveOrUpdate(sosCheque);

            }
           }
        }

         //   tx.begin();


         //   sf.close();
/*Session sf1 = HibernateUtil.getSessionFactory().getCurrentSession();
            Transaction tx1 = sf1.getTransaction();
             tx1.begin();*/

            if (cheque_no_hidden != null || cheque_amount_hidden != null || cheque_bank_hidden != null || cheque_date_hidden != null) {
                for (int i = 0; i < chequeCounter; i++) {



                    cheque_no = cheque_no_hidden.split(",");
                    cheque_amount = cheque_amount_hidden.split(",");
                    cheque_bank = cheque_bank_hidden.split(",");
                    cheque_date = cheque_date_hidden.split(",");

                    SOSChequeDetails sosChequeD = new SOSChequeDetails();
                    sosChequeD.setChequeNo(cheque_no[i]);
                    sosChequeD.setChequeAmount(cheque_amount[i]);
                    sosChequeD.setChequeBank(cheque_bank[i]);
                    sosChequeD.setChequeDate(cheque_date[i]);
                    sosChequeD.setCmaId(cmaId);
                    sosChequeD.setSosStage(flag);

                    sf.saveOrUpdate(sosChequeD);
               //     tx1.begin();


                 //   sf1.close();

                }

            }



 if(saveSOSValue.saveSOS(sosValues, cmaId,flag,sf,tx))
 {
     sosValues.setFlag(1);
 }
 else
 {
     sosValues.setFlag(2);
 }

 if(flag.equalsIgnoreCase("sosSUBMIT"))
 {
 CmaDetails  cmaD  = (CmaDetails) sf.get(CmaDetails.class, cmaId);

/* for(int j=0;j<5;j++){
     LeaveManagementManager manager=new LeaveManagementManager();
     Userinfo userinfoLeave=manager.getUserInfoObjforsos(sosWorkflow_status);

     workflow.setFromDesignation(userinfoLeave.getWorkflowdesignation().getWorkflowDesignationId());
     List<Workflow> workflowListTemp=new ArrayList<Workflow>();
     workflowListTemp=(new WorkflowService().performAction(workflow)); 

     if(userinfoLeave.getOutOfOffice()!=null && userinfoLeave.getOutOfOffice().equals("OOO")){
       date.setSeconds(date.getSeconds()+1);
       wfs=makeEntryInWorkflow(sdm,formater,now, date, workflowListTemp, cmaDetails, query, i, ToEmailIdTemp, ToEmailId,wfs,null);
     }else{
       j=5;
     }
     }*/

boolean decideRollback=approveSOSvalue.ApprovalSOSWorkflow(sosWorkflow_status,sosValues,cmaD,"create",1,"flag");  
if(decideRollback==false){
tx.rollback();

}
 }   
        } catch (Exception e) {
           if (tx!=null) tx.rollback();

           e.printStackTrace(); 
        }




        viewDocuments();
        viewCheques();
       /* ComplianceCMA complianceCMA = new ComplianceCMA();
        cmaDetails = complianceCMA.getCma(cmaId);
        cmaDetails.setStage(Constants.STAGE_SOS_UPLOAD);
        UpdateCMA updateStage = new UpdateCMA();
        updateStage.performAction(cmaDetails);*/


        ViewSOSDetails viewsos=new ViewSOSDetails();
        viewsos.home();
        return SUCCESS;
    }

This function calls

public boolean ApprovalSOSWorkflow(SOSWorkflow_status sosWorkflowstatuscomment,SOSValues sosValues,CmaDetails cmaId,String Action,int bpaID,String flag)

function. Please help.


Solution

  • Best way to solve this is to not use a new transaction in abc(). Start the transaction in xyz and use transaction prorogation required in abc(). That way Tx in abc() will lap onti the the Tx which xyz() started and if abc throws an exception catch it and rollback the Tx so that the Tx in Xyz also rolls back. Are you using Spring? If not then you should Spring makes solving such cases very easy using annotations.