在spring boot中使用spring数据jpa。
我有一个用例,我想销售n个产品,每次得到n+1个产品的请求。因此,我如何确保我应该只销售n个产品,而不满足所有其他请求。
假设任何产品id 1都有10个数量。同时收到了11个关于这个产品的请求。我如何才能确保系统只销售10个产品和失败的最后一个要求,因为缺货。
所有请求可以同时执行。
我正在使用mysql。
如果我使用@version,它将失败除第一个之外的所有其他事务。
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Version;
@Entity
public class ProductStockTable {
@javax.persistence.Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long Id;
private Long productId;
@Version
private Long version;
private Long currentStock;
public Long getId() {
return Id;
}
public void setId(Long id) {
Id = id;
}
public Long getProductId() {
return productId;
}
public void setProductId(Long productId) {
this.productId = productId;
}
public Long getVersion() {
return version;
}
public void setVersion(Long version) {
this.version = version;
}
public Long getCurrentStock() {
return currentStock;
}
public void setCurrentStock(Long currentStock) {
this.currentStock = currentStock;
}
}
@Transactional
public boolean checkStock(Long productId, Integer stock) {
ProductStockTable ps = stockRepo.findById(productId);
if (ps.getCurrentStock() > stock) {
ps.setCurrentStock(ps.getCurrentStock()-stock);
stockRepo.save(ps);
return true;
}
return false;
}
如果我做mysql约束 not negative
对于currentstock,它也不起作用。
有没有任何可能的方法来实现这一点在 Spring 开机?
2条答案
按热度按时间eh57zj3b1#
在进程完成之前调用checkstock函数?一次在开始,一次在结束,并直接更新数据库后,改变库存。
另一个选择可能是当你有一个请求被发送时-在完成之前更新股票(这样当它在别人的购物车中时就被锁定了)。在购物车上放置一个计时器,这样5分钟后它就会自动重新进货(我更喜欢选项1,更新数据库通常会放置一个临时锁,在更新完成之前停止select语句)
g6ll5ycj2#
你应该看看
LockMode
.一种解决办法是
PESSIMISTIC_WRITE
当你从你的书里读到这行的时候ProductStockTable
实体。此模式将阻止所有其他读取的发生,基本上可以将其视为该行上的独占锁,直到您完成它。一旦锁被释放,下一个竞争者就可以锁定它,以此类推。这将对在并发模式中频繁访问的行产生一些性能影响,但在重新评估其他替代方法之前,这是解决问题的一个很好的起点。