在進行類似批處理的程序時,如果在一個action中需要保存很多記錄數,這會導致grails中的數據庫session超過負荷,從而導致OOM。
因為這個情況的發生是由於在一次請求中,對數據進行的修改都保存在這個請求的數據庫session中,等這次請求結束後才會釋放這個數據庫session,這樣當本次請求中對數據修改的記錄數太多會導致OOM。
我們使用的是mongodb數據庫,而且使用的是grails mongodb plugin,即便我們使用這個plugin中的mongodb底層鏈接進行操作,還是依然發生了OOM。
因此我們想能夠使每次請求中只保留少量的修改數據在數據庫session中,這樣相當於對於具體數據的修改編寫在另一個action中。示例代碼如下:
def updateData(){ println "classId:${params.classId} usersId:${params.usersId}" render "ok" }
調用這個action的方法為:
println dataService.remoteCall(request, g.createLink(action: 'updateData', params: [classId:"test1", usersId:'usersIdxxx']))
這裡的實現關鍵是dataService.remoteCall的函數實現,具體如下:
/** * 得到協議和主機IP的url,最後不帶/ * 比如: * http://localhost:9090/blog/bkoff/testCaculateUserExedCount * 返回:http://localhost:9090 * @param request * @return */ private String getHostUrl(request){ String requestUrl = request.requestURL String seperator = "://" int index = requestUrl.indexOf("://") index = requestUrl.indexOf("/", index + seperator.length()) return requestUrl.substring(0, index) } /** * 遠程調用某方法,其中actionUrl用createLink方式就可以創建 * @param request * @param actionUrl * @return */ def String remoteCall(request, actionUrl){ def hostUrl = getHostUrl(request) def url = new URL(hostUrl + actionUrl) return url.text }