我有一个grails作业,计划每晚运行,以更新所有用户的统计数据,即firstOrderDate,lastOrderDate和totalOrders。
查看代码。
void updateOrderStatsForAllUsers(DateTime date) {
List<Order> usersByOrders = Delivery.findAllByDeliveryDateAndStatus(date, "DELIVERED")*.order
List<User> customers = usersByOrders*.customer.unique()
for (User u in customers) {
List<Order> orders = new ArrayList<Order>();
orders = u.orders?.findAll { it.status.equals("DELIVERED") }?.sort { it?.dateCreated }
if (orders?.size() > 0) {
u.firstOrderDate = orders?.first()?.dateCreated
u.lastOrderDate = orders?.last()?.dateCreated
u.totalOrders = orders.size()
u.save(flush: true)
}
}
}
并且运行此代码的作业是
def execute(){
long jobStartTime = System.currentTimeMillis()
emailService.sendJobStatusEmail(JOB_NAME, "STARTED", 0, null)
try {
// Daily job for updating user orders
DateTime yesterday = new DateTime().withZone(DateTimeZone.getDefault()).withTimeAtStartOfDay().minusDays(1)
userService.updateOrderStatsForAllUsers(yesterday)
emailService.sendJobStatusEmail(JOB_NAME, "FINISHED", jobStartTime, null)
}
catch (Exception e) {
emailService.sendJobStatusEmail(JOB_NAME, "FAILED", jobStartTime, e)
}
}
所以我发送邮件,对于发生的任何异常,现在问题是我总是收到&#34;错误:OptimisticLockingException&#34;在u.save()。约会时,我有大约400名用户。
我知道为什么乐观锁定会发生,但是你可以看到我没有在循环中更新相同的用户记录,我有一个不同用户的列表,我正在迭代它们来更新所有这些。那我怎么得到用户保存的乐观锁定异常。帮助!
答案 0 :(得分:0)
乐观锁定是一个休眠错误,Mango DB与此无关。
什么实体抛出乐观锁定异常是客户还是订单或交付?
在此作业运行时,您如何确保这些实体在应用程序的其他位置都不会更新?
您如何确保此作业一次只能被触发一次?
尝试添加一些日志记录,通过在上一次执行完成后再次触发作业来查看它是一个可重复的问题。
更多调试可能有助于解决问题。
答案 1 :(得分:0)
石英作业通常不为其操作提供TX上下文,因此您应该手动将方法包装到事务中:
def execute(){
...
User.withTransaction{ tx ->
userService.updateOrderStatsForAllUsers(yesterday)
}
....
}