В моем приложении Grails я создаю множество отдельных DomainObject
во время одного вызова ссылки сохранения:
import grails.converters.JSON
class SaveController {
def saveService
def save() {
println (new Date()) + " Enter SaveController.save()."
Map status = saveService.save(params)
println (new Date()) + " Finished calling saveService.save()."
render status as JSON
}
}
Ссылка вызывает службу для сохранения каждого ее содержимого в базе данных.:
import org.codehaus.groovy.grails.web.servlet.mvc.GrailsParameterMap
class SaveService {
Map save(GrailsParameterMap params) {
List<DomainObject> dos = new ArrayList()
println (new Date()) + " Iterate list and create DomainObject per element."
params.list.each { l ->
dos.push(new DomainObject(l))
}
println (new Date()) + " Started saving all DomainObjects."
dos.each { d ->
d.save()
}
println (new Date()) + " Finished saving all ${dos.size()} DomainObjects."
return [done: true]
}
}
Проблема в том, что он задыхается в определенной части процесса, что очевидно для отпечатков, которые я разместил:
Fri Jun 01 21:47:55 SGT 2018 Enter SaveController.save().
Fri Jun 01 21:47:55 SGT 2018 Iterate list and create DomainObject per element.
Fri Jun 01 21:47:55 SGT 2018 Started saving all DomainObject.
Fri Jun 01 21:48:13 SGT 2018 Finished saving all 4316 DomainObject.
// Waits from some minutes before reaching the next println.
Fri Jun 01 21:52:02 SGT 2018 Finished calling saveService.save().
Я предполагаю, что это требует времени для сохранения /совершая каждый отдельный .save()
вызов в базу данных.У меня вопрос, есть ли способ, которым я могу изменить код, чтобы он фиксировал все элементы List<DomainObject> dos
один раз в целом, тем самым исключая длительное время, необходимое для выхода из saveService.save()
.
Я пытался изменить d.save()
на d.save(flush: true)
, но скорость осталась прежней.Я ищу, может быть, отличный Closure
, который будет автоматически фиксировать транзакции внутри него, когда это будет сделано, что-то вроде этого (я не знаю, есть ли фактический Closure
как это):
commitOnceDone { session ->
dos.each { d ->
d.save()
}
}
// Once reached here, will fire a single COMMIT; that will affect
// all transactions that happened inside the Closure