gpt4 book ai didi

hibernate - JPA/Hibernate 如何正确增加数据库中的计数器?

转载 作者:行者123 更新时间:2023-12-03 06:57:53 25 4
gpt4 key购买 nike

也许这对某些人来说听起来是一个简单的问题,但是在数据库中增加计数器的正确方法是什么?

例如,如果我有一个包含“like_count”列的表,每次用户喜欢照片时该列都会更新。

(假设我有我的照片@Entity)

Photo photo = photoRepository.findByPhotoId(id)
photo.setLikeCount(photo.getLikeCount()+1);
photoRepository.save(photo)

例如,上面的代码正确吗?会发生任何竞争条件吗?

谢谢

最佳答案

我认为代码不正确。并行运行的线程稍后完成更新,但之前读取过相同的计数器,将覆盖计数器,因此会丢失一个计数。

这还取决于事务隔离级别,如果您使用SERIALIZATION或“REPEATABLE_READ”,您是安全的,但通常使用READ COMMITTED,这会显示此问题通常与 Oracle 或 PostgreSQL 等数据库有关。

还值得注意的是,默认情况下,至少 Hibernate 会保存完整的实体,而不仅仅是修改的列。因此更改不同的列不起作用。您可以使用 @DynamicUpdate 更改此设置,但这种硬行为更改可能会产生一些副作用,至少对于刷新到数据库的字段的脏检查的性能而言。

解决方案:

正确的解决方案是:

  1. 悲观锁定:使用SELECT ... FOR UPDATE锁定行 - 不好,这可能会降低性能,因为所有写入者都必须等待,如果写入者处于事件状态,所有读取者也必须等待
  2. 原子更新:更好,因为它不使用悲观锁定:更新照片设置 likecount = likecount + 1 WHERE id = :id
  3. 乐观锁定方法。但随后您必须处理 OptimisticLockingExceptions 并重复事务

关于hibernate - JPA/Hibernate 如何正确增加数据库中的计数器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27284487/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com