我们经常在日常代码中找到这种情况。我们想检查db中是否存在某些记录,如果存在,则不执行任何操作,但如果记录丢失则执行操作然后插入记录。
例如在发送推送通知时,我们只想发送通知(如果尚未发送)。
我们可以用两种方式编写代码
首先检查notificationSent
boolean notificationSent = notificationDao.checkNotificationId(notificationId);
if(notificationSent){
return;
}
else{
//send notification
notificationDao.insertNotification(notificationModel);
}
另一种方式是尝试捕获
try{
notificationDao.insertNotification(notificationModel);
//send notification
}
catch(DuplicateKeyException e){
// log and do nothing
}
在第二种情况下,如果我们在发送实际通知时遇到异常,我们只需回滚插入。所以第一种和第二种方法在功能上并不相同。
但在第一种情况下,我们在第二种情况下保存数据库调用时会进行2次db调用。总体上更好的方法是什么?
关于性能,第二种方法更好,除非重复频率很高。虽然异常成本很高,但访问数据库的成本更高。
请注意,在您检查之后,可能会有另一个线程或进程在您之前插入通知。因此,一般来说,您可能希望将两种方法结合起来:
boolean notificationSent = notificationDao.checkNotificationId(notificationId);
if (notificationSent) {
return;
}
try {
notificationDao.insertNotification(notificationModel);
} catch (DuplicateKeyException e){
// log and do nothing
}
无论如何,获得非特殊情况的例外情况并不合适。我会选择合并的方法,只有在性能需要时才进行优化。例如,有时,缓存最近发送的通知可能会节省大多数数据库读取。
我也认为第二种情况对你的例子更好。