问题描述
我正在使用CrudRepository的spring框架的saveAll方法。
validationRowRepository.saveAll(validationRows);
现在,当我们确保将当前批处理持久化到数据库中并提交了事务时,我只有执行下一步的要求。
通过查看saveAll方法规范,我决定采用这种方式进行检查。
List<ValidationRow> savedRows = (List<ValidationRow>) validationRowRepository.saveAll(validationRows);
if (Objects.equals(savedRows.size(),validationRows.size()) {
// do the next step.
}
即使这是真的,那么如果执行不输入if块会发生什么呢? 所以我的问题是: 有没有更合适的方法来实现这种情况。
解决方法
有两点要考虑:
- 将数据写入数据库
- 提交交易
saveAll
的合同如下:
所有实体将被写入数据库。如果这对于至少一个实体不起作用,则将引发异常。 saveAll
的返回值将始终具有与输入值相同的大小。它不会包含null
值。所有包含的实体都将设置其id值(对象类型不是null
,原始数字类型不是0
因此,您的if条件是多余的,并在Spring Data JDBC中测试一个非常特定的错误。有意义的是进行一个测试(作为实际的JUnit测试),以使您的实体可以在保存后加载并看上去像检查一样。基本上,这将是对对象模型,数据库模式,映射和Spring Data JDBC中实现的逻辑的一致性的测试。很多事情可能会出错。对此进行测试很好。
您的代码甚至没有涉及交易的主题。控制交易的主要方法有两种:
两者均基于Spring事务基础结构,该结构可确保在事务提交失败时引发异常。类似于我在上面写的内容,编写一个测试(即检查事务是否按预期运行的JUnit测试)可能有意义。尽管这可能很困难,因为您必须注入某种数据库故障才能做到这一点。
因此,实际代码剩下的就是处理调用saveAll
时可能引发的任何异常。由于使用TransactionTemplate
更容易移动事务边界,因此我在示例代码中使用了它。
try {
validationRows = txTemplate.execute( t -> validationRowRepository.saveAll(validationRows));
process(validationRows) // do whatever you want to do with the entities after saving
} catch (DataAccessException e) {
// do whatever you see fit in the case of an exception. You might also skip the try catch block and just let the exception terminate the process,or in case of a web application the request.
}
,
如果您致电saveAll
,则必须保存数据。在其他情况下,必须抛出异常,然后您才能处理可能的异常。您编写的代码是正确的,并且您确实不需要执行高级安全性。 ;)