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

23 浏览
0 Comments

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

我在使用Spring和JPA/Hibernate进行一些尝试,并且对于在表中递增计数器的正确方法感到有些困惑。

我的REST API需要根据用户的操作(在下面的示例中,喜欢或不喜欢一个标签将使计数器在Tag表中递增或递减一)

tagRepository是一个JpaRepository(Spring-data)

我已经像这样配置了事务

@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秒的睡眠时间,以便测试并发场景。

初始标签计数器= 10;

1)用户调用increaseTag并且代码进入睡眠状态,因此实体的值= 11,数据库中的值仍然为10

2)用户调用decreaseTag并通过所有代码。数据库中的值现在= 9

3)睡眠结束并且实体具有计数为11的值,然后进行.save()

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

这种行为正常吗?还是@Transactional注释没有起作用?

0