在進行類似批處理的程序時,如果在一個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
}