将数据保存到数据库时,我真的想知道保存的数据。但我的spring应用程序似乎没有抛出错误/异常。
所以我所做的就是在保存操作myRepository.save(entity)
之前在我的应用程序中设置一个断点。当它在断点处停止时,我停止了我的数据库服务,然后继续保存。
我没有例外,save()
返回的保存实体看起来很好。但是DB中没有保存任何东西。我甚至可以myRepository.findOne(id)
,它会找到实体。我怎么知道它真的得救了?
如果数据库在我的@Transactional
方法之前出现故障,那么我会收到错误,但不会在方法中间停止。
答案 0 :(得分:1)
所有这些操作都将在内存中完成,直到调用commit。提交后,它将持久保存到相应的dbs中。在提交之后,db将调用与db相关的触发器,例如foriegn key / related stuffs,如果出现错误,则抛出其他存储库将简单地返回实体对象。
答案 1 :(得分:1)
repository.save()
不一定会刷新对数据库的更改。它只会在以下情况下这样做:
@Transactional
方法的结束)repository.findAll()
或repository.findOne(id)
时)Hibernate documentation以及交易后写中提到了这一点:
要减少数据库中的锁争用,物理数据库事务需要尽可能短。长数据库事务会阻止您的应用程序扩展到高度并发的负载。不要在最终用户级工作期间打开数据库事务,而是在最终用户级工作完成后打开它。这个概念被称为事务性后写。
这意味着如果您的数据库在刷新更改时正在关闭,那么您实际上应该得到一个例外。但是,这可能发生在方法结束时,在其他地方,......。
这也是为什么有时难以追踪异常发生原因的原因,因为冲洗可能比代码中实际保存发生的时间要晚得多。
如果您使用repository.flush()
或repository.saveAndFlush()
方法,您可以在必要时手动刷新到数据库,但通常您不应该这样做。
答案 2 :(得分:1)
解决方案是将我的数据库调用myRepository.save(entity)
包装在服务类或使用@Transactional
注释的单独方法中。
这种方式调用方法时,@Transactional
,我会抛出一个异常。由于提交是在调用方法之后完成的。感谢您Maria Sekar的见解。之前我在Controller上有@Transactional
注释,这给了我一个错误,但我没有机会对它做任何事情。
所以解决方案,简化
在Controller类中
@RequestMapping(value = "/notification", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public Notification saveNotification(@RequestBody Notification notification) {
Notification savedNotification = null;
try {
myService.save(notification);
} catch (SQLServerException e) {
throw new CouldNotSaveNotification(e);
}
return savedNotification;
}
在服务类
@Transactional
public save(Notification notification) {
myRepo.save(notification);
}