gpt4 book ai didi

java - Spring、JPA 和 Hibernate - 如何在没有并发问题的情况下增加计数器

转载 作者:IT老高 更新时间:2023-10-28 13:47:55 24 4
gpt4 key购买 nike

我正在使用 Spring 和 JPA/Hibernate,但我对在表中增加计数器的正确方法有点困惑。

我的 REST API 需要根据用户操作增加和减少数据库中的某些值(在下面的示例中,喜欢或不喜欢标签将使标签表中的计数器增加或减少 1)

tagRepository 是一个 JpaRepository (Spring-data)我已经像这样配置了事务

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"/>

@Controller
public class TestController {

@Autowired
TagService tagService

public void increaseTag() {
tagService.increaseTagcount();
}
public void decreaseTag() {
tagService.decreaseTagcount();

}
}

@Transactional
@Service
public class TagServiceImpl implements TagService {


public void decreaseTagcount() {
Tag tag = tagRepository.findOne(tagId);
decrement(tag)
}

public void increaseTagcount() {
Tag tag = tagRepository.findOne(tagId);
increment(tag)
}

private void increment(Tag tag) {
tag.setCount(tag.getCount() + 1);
Thread.sleep(20000);
tagRepository.save(tag);
}

private void decrement(Tag tag) {
tag.setCount(tag.getCount() - 1);
tagRepository.save(tag);
}
}

如您所见,我特意在 .save() 之前增加了 20 秒的 sleep 时间,以便能够测试并发场景。

初始标签计数器 = 10;

1) A user calls increaseTag and the code hits the sleep so the value of the entity = 11 and the value in the DB is still 10

2) a user calls the decreaseTag and goes through all the code. the value is the database is now = 9

3) The sleeps finishes and hits the .save with the entity having a count of 11 and then hits .save()

当我检查数据库时,该标签的值现在等于 11.. 而实际上(至少我想要实现的)它会等于 10

这种行为正常吗?还是 @Transactional 注释没有做的工作?

最佳答案

最简单的解决方案是将并发委托(delegate)给您的数据库,并简单地依赖当前修改的行上的数据库隔离级别锁:

增量就这么简单:

UPDATE Tag t set t.count = t.count + 1 WHERE t.id = :id;

减量查询为:

UPDATE Tag t set t.count = t.count - 1 WHERE t.id = :id;

UPDATE 查询对修改的行进行锁定,防止其他事务在当前事务提交之前修改同一行(只要您不使用 READ_UNCOMMITTED)。

关于java - Spring、JPA 和 Hibernate - 如何在没有并发问题的情况下增加计数器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30143594/

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