Java+MySQL实现电商购物车 数据库设计与并发操作处理
·
数据库设计
购物车表 (cart)
CREATE TABLE cart (
cart_id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
product_id INT NOT NULL,
quantity INT NOT NULL DEFAULT 1,
selected BOOLEAN DEFAULT TRUE,
created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES user(user_id),
FOREIGN KEY (product_id) REFERENCES product(product_id),
UNIQUE KEY (user_id, product_id)
);
商品表 (product)
CREATE TABLE product (
product_id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
price DECIMAL(10,2) NOT NULL,
stock INT NOT NULL,
status TINYINT DEFAULT 1
);
用户表 (user)
CREATE TABLE user (
user_id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE
);
并发操作处理
乐观锁实现 在商品表中添加version字段:
ALTER TABLE product ADD COLUMN version INT DEFAULT 0;
Java代码示例:
public boolean addToCart(int userId, int productId, int quantity) {
// 查询商品信息并检查库存
Product product = productMapper.selectById(productId);
if (product.getStock() < quantity) {
return false;
}
// 更新商品库存(带乐观锁)
int updated = productMapper.updateStockWithVersion(
productId,
quantity,
product.getVersion()
);
if (updated == 0) {
// 版本号不匹配,更新失败
throw new OptimisticLockException("商品库存发生变化,请重试");
}
// 添加或更新购物车
Cart cart = cartMapper.selectByUserAndProduct(userId, productId);
if (cart == null) {
cart = new Cart();
cart.setUserId(userId);
cart.setProductId(productId);
cart.setQuantity(quantity);
cartMapper.insert(cart);
} else {
cart.setQuantity(cart.getQuantity() + quantity);
cartMapper.updateById(cart);
}
return true;
}
悲观锁实现 使用SELECT...FOR UPDATE锁定商品记录:
@Transactional
public boolean addToCartWithPessimisticLock(int userId, int productId, int quantity) {
// 锁定商品记录
Product product = productMapper.selectByIdForUpdate(productId);
if (product.getStock() < quantity) {
return false;
}
// 更新库存
productMapper.updateStock(productId, quantity);
// 更新购物车(同上)
// ...
return true;
}
购物车关键操作
获取用户购物车
public List<CartVO> getCartList(int userId) {
return cartMapper.selectCartListWithProductInfo(userId);
}
更新购物车商品数量
@Transactional
public boolean updateCartQuantity(int cartId, int quantity) {
Cart cart = cartMapper.selectById(cartId);
if (cart == null) {
return false;
}
Product product = productMapper.selectById(cart.getProductId());
if (product.getStock() < quantity) {
return false;
}
cart.setQuantity(quantity);
cartMapper.updateById(cart);
return true;
}
批量删除购物车商品
@Transactional
public int batchDeleteCartItems(int userId, List<Integer> cartIds) {
return cartMapper.batchDelete(userId, cartIds);
}
性能优化建议
使用Redis缓存热门商品信息,减少数据库查询压力
对大流量场景,考虑使用Redis暂存购物车数据,定期同步到MySQL
为购物车表添加复合索引 (user_id, product_id) 提高查询效率
在高并发场景下,使用消息队列异步处理非核心操作
更多推荐




所有评论(0)