gpt4 book ai didi

java - JPA 两个事务更新相同的行

转载 作者:行者123 更新时间:2023-11-29 06:56:06 25 4
gpt4 key购买 nike

我在 SpringBoot 应用程序中使用 JPA 存储库,我有一个后台任务,定期将数据库中的某些元素设置为“就绪”我还有一个端点,用户可以调用该端点,并且可以修改同一表的行之一。

有没有办法避免一个又一个取消对方的写入?以这个场景为例

Table: 
Key
id name is_ready

0) 初始数据有一个键 (1 no_name false)

1)后台任务启动,即将通过设置修改表Key

is_ready to true
Key key = repo.findKeyByIsReady(false)
key.setIsReady(true)
repo.save(key) <--- does NOT yet execute this

2) 用户调用 api 端点将 key 名称更改为“new_name”并完成

3)现在后台服务执行repo.save(key),最终数据为

1    no_name   true 

而不是

1    new_name   true

基本上后台任务已经覆盖了用户设置的键名

有没有办法避免这种情况发生?交易在这里有何帮助?

最佳答案

这通常可以通过额外的锁来解决:

乐观锁

您在第二个事务中检测到该行已被其他人更改。然后,您要么告诉用户并要求手动修复,要么尝试自动合并更改。

要实现它,您必须向表中添加附加列 - 版本。然后,当更新行时,查询将如下所示:

UPDATE ..., version=old_version+1 WHERE id=old_id and version=old_version

如果 WHERE close 找不到该行(因为其他人增加了版本),则更改的行数将为 0(JDBC 从数据库获取此信息)并且 JPA 将抛出错误在这种情况下。

附加字段必须在 JPA 中映射为 @Version

悲观锁

每次更新实体时,您都会使用构造:

select ... for update

当第二个事务发出此类语句时,数据库会锁定该请求,直到第一个事务完成。如果在特定时间段内没有发生这种情况,您会收到 JPA 的异常。请参阅 EntityManager#lock() 方法了解更多信息。

关于java - JPA 两个事务更新相同的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45544248/

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