fenixsoft / fenixsoft/monolithic_arch_springboot

商品库存的领域服务的读改写问题

Open
#14 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
570
Forks
324
PR merge metrics
No merged PRs in 30d

Description

```java
/**
* 货物冻结
* 从正常货物中移动指定数量至冻结状态
*/
public void frozen(Integer productId, Integer amount) {
Stockpile stock = repository.findById(productId).orElseThrow(() -> new EntityNotFoundException(productId.toString()));
stock.frozen(amount);
repository.save(stock);
log.info("冻结库存,商品:{},数量:{}", productId, amount);
}
```
我想请教一下:上面的代码中,先从数据库中读取了指定商品的库存,然后在Java层面上进行修改,接着将修改后的结果保存到数据库,这不会产生“读──改──写”问题吗?
假如两个线程A和B同时执行`frozen`方法,假设此时数据库事务使用的是“可重复读”隔离级别,假设此时P商品的库存是10(amount是10,frozen是0),那么A和B两个线程从仓库中取出来的stock中的amount都是10,此时假设A线程把stock.amount改为了8(相应地stock.frozen变为了2),接着A线程提交事务,接着B线程也修改stock,将stock.amount改为了6(相应地stock.frozen变成了4),此时线程B也提交事务。B线程提交完事务后,数据库中P商品的库存是6(冻结库存是4),这不是有问题吗?按照我的理解,A和B这两个事务都提交成功之后,数据库中P商品的库存应该是4才对(冻结库存是6)。也就是说,正常来说,在查询库存的时候就要对库存这条记录进行锁定读(select for update),保证整个读改写操作是原子的。

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.