2016-04-01 49 views
0
def saveProcessDetail = { 

    //def employeeLoanInstance = EmployeeLoan?.findById(params?.long("id"),[lock: true]) 
    //lock(params?.long("id")) 
    def employeeLoanInstance = EmployeeLoan?.get(params?.long("id")) 
    if(employeeLoanInstance){ 
     def instance 
     if(params?.modeOfPayment){ 
      if(params.modeOfPayment == 'DD'){ 
       params.ddDate = params.ddDate ? DateUtility?.parseDate(params.ddDate) : params.ddDate 
       instance = new Dd() 
      } 
      if(params.modeOfPayment == 'Cheque'){ 
       params.chequeDate = params.chequeDate ? DateUtility?.parseDate(params.chequeDate) : params.chequeDate 
       instance = new Cheque() 
      } 
      if(params.modeOfPayment == 'Cash'){ 
       params.paidDate = params.paidDate ? DateUtility?.parseDate(params.paidDate) : params.paidDate 
       instance = new Cash() 
      } 
      instance?.properties = params 
     } 

     params.deductionDate = params.deductionDate ? DateUtility?.parseLoanDate(params.deductionDate) : params.deductionDate 
     params.sanctionedDate = params.sanctionedDate ? DateUtility?.parseDate(params.sanctionedDate) : params.sanctionedDate 

     //println " test : "+DateUtility.getFormattedMonthAndYear(params.deductionDate) 
     //println " test zx : "+DateUtility.getFormattedMonthAndYear(params.sanctionedDate) 
     def formattedDeductionDate = DateUtility.getFormattedMonthAndYear(params.deductionDate) 
     def formattedSanctionedDate = DateUtility.getFormattedMonthAndYear(params.sanctionedDate) 


     //println " less : "+(formattedDeductionDate < formattedSanctionedDate) 

     //println " = : "+(formattedDeductionDate == formattedSanctionedDate) 


     //println " greater : "+(formattedDeductionDate > formattedSanctionedDate) 

    // formattedDeductionDate.before(formattedSanctionedDate) && !(formattedDeductionDate.equals(formattedSanctionedDate)) 


     employeeLoanInstance?.properties = params 
     instance?.validate() 
     if(params.modeOfPayment == 'Cash' && employeeLoanInstance?.sanctionedAmount && instance?.cashAmount && (instance?.cashAmount != employeeLoanInstance?.sanctionedAmount)) 
      instance.errors.rejectValue ("cashAmount", "cash.cashAmount.invalid.message", [ 
       message(code : 'cash.cashAmount.label', default : 'Amount')] 
      as Object[], message(code : 'cash.cashAmount.invalid.message')) 
     if(!instance?.hasErrors()) 
      employeeLoanInstance.loanId = employeeLoanInstance.loanId ? employeeLoanInstance.loanId : loanService?.getLoanId(employeeLoanInstance?.employee,employeeLoanInstance?.createdBranch) 
     employeeLoanInstance?.validate() 
     /* Emi Amount Validation */ 
     if(employeeLoanInstance?.noOfInstallments && employeeLoanInstance?.emiAmount && employeeLoanInstance?.sanctionedAmount){ 
      def amt = (employeeLoanInstance?.noOfInstallments - 1) * (employeeLoanInstance?.emiAmount) 
      def sanctionedAmt = (employeeLoanInstance?.sanctionedAmount - amt) 
      if(amt > employeeLoanInstance?.sanctionedAmount) 
       employeeLoanInstance.errors.rejectValue ("emiAmount", "employeeLoan.emiAmount.invalid.message", [ 
        message(code : 'employeeLoan.emiAmount.label', default : 'Emi Amount')] 
       as Object[], message(code : 'employeeLoan.emiAmount.invalid.message')) 
      if(sanctionedAmt > employeeLoanInstance?.emiAmount) 
       employeeLoanInstance.errors.rejectValue ("emiAmount", "employeeLoan.emiAmount.invalid.message", [ 
        message(code : 'employeeLoan.emiAmount.label', default : 'Emi Amount')] 
       as Object[], message(code : 'employeeLoan.emiAmount.invalid.message')) 
     } 
     /* End */ 
     if(!(employeeLoanInstance?.hasErrors()) && !(instance?.hasErrors())){ 
      instance?.save(flush : true) 
      employeeLoanInstance.paymentId = instance?.id 
      employeeLoanInstance.outstandingAmount = employeeLoanInstance?.sanctionedAmount 
      employeeLoanInstance?.save(flush : true) 
      println"employeeLoanInstance?.noOfInstallments"+employeeLoanInstance?.noOfInstallments 
      println "-------loan instance----------->"+employeeLoanInstance?.errors 
      /* For saving EmiAmount Details */ 
      def emiMonth = params.deductionDate 
      def amt = 0 
      if(employeeLoanInstance?.noOfInstallments){ 
      for(int i = 0; i < Integer?.valueOf(employeeLoanInstance?.noOfInstallments); i++){ 
       amt = employeeLoanInstance?.emiAmount 
       if(i > 0){ 
        Calendar calendar = GregorianCalendar.getInstance() 
        Integer year = emiMonth?.year+1900 
        Integer month = (emiMonth?.month) + 1 
        Integer date = emiMonth.getAt(Calendar.DAY_OF_MONTH) 
        //calendar.set (year, month, date) 
        calendar.set(year, month, date, 0, 0, 0) 
        emiMonth = calendar?.getTime() 
       } 
       if(i == (employeeLoanInstance?.noOfInstallments - 1)){ 
        amt = employeeLoanInstance?.sanctionedAmount - (employeeLoanInstance?.emiAmount * (employeeLoanInstance?.noOfInstallments - 1)) 
       } 
       def emiAmountInstance = new EMIAmountDetails() 
       emiAmountInstance?.emiMonth = emiMonth 
       emiAmountInstance?.emiAmount = amt 
       emiAmountInstance?.loanId = employeeLoanInstance.loanId 
       auditService.beforeSave(emiAmountInstance) 
       emiAmountInstance?.save(flush : true) 
      } 
      } 
      /* End */ 

      flash.message = "${message(code : 'loanApproval.created.message', args : [employeeLoanInstance?.loanType,loanService?.getName(employeeLoanInstance.employee.empPersonalDetails),message(code : 'employeeLoan.loanStatus.'+employeeLoanInstance?.loanStatus)])}" 
      redirect(action : "list") 
     } 
     else{ 
      render(template : "processLoan", model : [screenName : params?.screenName,instance:instance,employeeLoanInstance : employeeLoanInstance, methodName : params?.methodName]) 
     } 
    } 
    else{ 
     flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'employeeLoan.label', default: 'EmployeeLoan'), params.id])}" 
     redirect(action : "list") 
    } 
} 

注:我無法通過各種scenario.but當本地重現此問題我查看生產服務器日誌文件上面的問題不斷髮生。讓我把它的代碼塊同步一個或其他服務層的事務management.line實例?.save(flush:true)導致問題確切..請給你的想法前進org.hibernate.StaleObjectStateException:行被其它事務更新或刪除(或者未保存值的映射是不正確的)[COM#117591]

回答

1

你一定要移動你的數據庫訪問到一個交易服務。儘管如此,這並不一定會阻止這個問題。此外,同步絕對不是這裏的方式

這是一個樂觀鎖定失敗。 (請參閱https://grails.github.io/grails-doc/latest/guide/GORM.html#locking

根據您提供的信息,我無法提供明確的答案,但基於之前所見,我懷疑您有雙擊問題:用戶正在觸發在第一個動作完成之前再次執行動作。第一個操作完成並更新受影響對象的版本。當第二個動作寫入數據庫時​​,它會失敗,因爲對象的版本在對象加載後已更新。

爲了幫助驗證這是否是問題,您應該將日誌記錄添加到您的生產系統,以便您可以看到此方法何時啓動以及標識是什麼。如果您看到具有幾乎相同時間戳的同一對象的兩個(或更多)日誌條目,那麼這就是您的問題。

要解決它,請修改您的網頁以阻止雙擊或修改您的代碼以接受StaleObjectStateException。

+0

感謝您的回覆@ foundart ..我檢查了雙擊問題,但沒有這樣的東西。已經沒有辦法雙擊...所以我打算部署戰爭文件與日誌系統,以便我能夠確切地找出問題。 –

相關問題