提供表格:
CREATE TABLE mytable (
some_id BIGINT PRIMARY KEY NOT NULL,
timestamp TIMESTAMP WITH TIME ZONE NOT NULL
);
实体:
@Entity
@Table(name = "mytable")
class Thing(
@Id
var some_id: Long,
var timestamp = ZonedDateTime.now()
)
存储库:
interface MyRepo : JpaRepository<Thing, Long>
这个循环:
val myRepo: MyRepo
while (True) {
val some_id: Long = ComesFromSomewhere()
if (myRepo.findById(some_id) == null) {
myRepo.save(Thing(some_id))
}
}
目的是仅在ID首次出现时为该ID存储时间戳。
上面的代码可以工作,但是在我的用例中每秒导致超过100 save
个事务,这给数据库带来了沉重的负担。因此,我想进行优化,累积一批Thing
,然后使用类似saveAll
的东西在一次交易中完成所有操作。
不过,仅使用saveAll
也会覆盖表中已经存在的ID的时间戳,这不是故意的。
在没有太多低级代码的情况下如何解决?
答案 0 :(得分:1)
如果将上述循环放在@Transactional方法中,则应该只有1个事务-当然,有很多INSERT和SELECT-事务,但是只有1个事务。这将减轻数据库的负担。
此外,在这种情况下,save()是调用的正确方法。还有一种名为saveAndFlush()的方法,与您想要的相反。
您还可以通过执行repo.findAllById()而不是很多findById()来限制SELECT的数量。