![](/img/trans.png)
[英]@UpdateTimestamp is not updating with latest timestamp Spring Boot Data JPA
[英]Spring Data not updating on latest data
我的SQL表中有一个字段,需要更新一个字段并返回唯一的ID。 但是看起来它并没有根据最新数据进行更新,尤其是当我发出很多请求时。
@Transactional
public interface CompanyRepository extends CrudRepository<Company, Integer> {
@Modifying(clearAutomatically = true, flushAutomatically = true)
@Query(value = "update Company c set c.accessId = :accessId WHERE c.id = :companyId AND c.accessId = :oldAccessId", nativeQuery = true)
int updateAccessId(@Param("companyId") Integer companyId, @Param("accessId") Integer accessId, @Param("oldAccessId") Integer oldAccessId);
}
即使将clearAutomatically和flushAutomatically都设置为true,它也不会对最新数据起作用。
我可以看到两个更新查询都与oldAccessId一样成功。
桌子的设计应该改变吗?
PS:我也尝试过不使用nativeQuery = true。
您在这里拥有的是经典的比赛条件。
两个线程读取具有相同accessId
的相同实体,将其递增1,然后使用问题中显示的方法写入结果。 结果实际上只有一个更新。
有多种解决方法。
使用JPA和乐观锁定。
假设您有一个带有@Version
注释的属性, @Version
可以在单个事务方法中执行以下操作:
accessId
。 如果另一个事务试图在同一实体上执行相同操作,则两者之一将获得异常。 在这种情况下,请重试,直到更新完成。
使用数据库。
使读取和更新数据库中的原子。 与其传递新值作为参数,不如使用以下查询:
update Company c set c.accessId = c.accessId + 1 WHERE c.id = :companyId
使其成为版本属性。
如上所述,JPA已经具有@Version
属性,该属性在每次更改时都会更新。 根据确切的要求,您也许可以使accessId
只是该属性,并使其自动更新。
检查是否有任何行被更新。
根据您的评论,您的意图是基本上重新实现JPA对版本属性的操作。 如果这样做,您将丢失一个关键部分:通过将返回值与1进行比较,检查更新是否确实更新了任何内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.