Spring Boot 我应该使用哪种类型的锁来实现推车?

hm2xizp9  于 5个月前  发布在  Spring
关注(0)|答案(1)|浏览(48)

我目前正在为我的电子商务网站实现一个购物车功能。当前代码从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.");
            }
        }

字符串
这是否足以解决问题?

hfwmuf9z

hfwmuf9z1#

当使用LockModeType.PESSIMISTIC_WRITE调用entityManager.find时,它会告诉JPA提供程序在检索到的Product实体上获取一个悲观写锁。该锁可以防止其他事务在相同数据上获取写锁,直到锁被释放(事务被提交或回滚)。
因此,在两个事务(T1和T2)并发执行addToCart方法的场景中:

  • 如果T1首先到达获取悲观写锁的行,它将获得锁,如果T2试图获取同一个Product实体上的锁,它将被阻塞。
  • 如果T2首先到达获取悲观写锁的行,则它将获取锁,并且如果T1尝试获取相同Product实体上的锁,则T1将被阻塞。

如果预期冲突很少发生,则可以考虑改用乐观锁定。
乐观锁定可以在冲突很少的情况下带来更好的性能。它避免了在事务期间锁定数据,允许多个事务同时读取相同的数据。

相关问题