我目前正在为我的电子商务网站实现一个购物车功能。当前代码从product表中读取一条记录,检查可用数量是否大于或等于请求数量,然后相应地减少数量(即new_quantity = available_quantity - requested_quantity)。
问题是当两笔交易(我们称之为T1和T2)同时读取初始数量值(假设是10)。T1请求3个单位,T2请求8个单位。如果T1将数量减少3以获得7,则已经读取旧数据的T2可能会将新值设置为2(即,10 - 8)。在这种情况下,我应该如何处理此并发问题以确保准确的数量更新?
我遇到了一个使用锁的解决方案.但我不确定这是否会解决这个问题.是锁类型正确还是我应该使用其他锁.我目前正在使用此代码代码.
@Transactional
public void addToCart(CartDTO cartItem) throws Exception{
Product product = entityManager.find(Product.class, cartItem.getProductId(), LockModeType.PESSIMISTIC_WRITE);
if (product.getQuantity() >= cartItem.getQuantity()) {
product.setQuantity(product.getQuantity() - cartItem.getQuantity());
Cart newCartItem = new Cart();
newCartItem.setCustomer(entityManager.find(Customer.class, cartItem.getCustomerId()));
newCartItem.setProduct(product);
newCartItem.setQuantity(cartItem.getQuantity());
entityManager.persist(newCartItem);
}
else {
throw new Exception("Quantity in cart more that the available quantity.");
}
}
字符串
这是否足以解决问题?
1条答案
按热度按时间hfwmuf9z1#
当使用
LockModeType.PESSIMISTIC_WRITE
调用entityManager.find
时,它会告诉JPA提供程序在检索到的Product
实体上获取一个悲观写锁。该锁可以防止其他事务在相同数据上获取写锁,直到锁被释放(事务被提交或回滚)。因此,在两个事务(T1和T2)并发执行
addToCart
方法的场景中:Product
实体上的锁,它将被阻塞。Product
实体上的锁,则T1将被阻塞。如果预期冲突很少发生,则可以考虑改用乐观锁定。
乐观锁定可以在冲突很少的情况下带来更好的性能。它避免了在事务期间锁定数据,允许多个事务同时读取相同的数据。