avatar

目录
complex-transaction-example

复杂事务示例:电子商务订单处理

假设我们有以下表:

  • 商品 (产品ID, 名称, 价格, 库存)
  • 用户 (用户ID, 名称, 余额)
  • 订单 (订单ID, 用户ID, 总价, 状态)
  • 订单项目 (订单ID, 产品ID, 数量, 单价)

以下是一个复杂的事务,处理创建订单的过程:

sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
BEGIN TRANSACTION;

DECLARE @OrderID INT;
DECLARE @UserID INT = 1001;
DECLARE @TotalAmount DECIMAL(10, 2) = 0;

-- 创建新订单
INSERT INTO 订单 (用户ID, 总价, 状态)
VALUES (@UserID, 0, '处理中');

SET @OrderID = SCOPE_IDENTITY();

-- 添加订单项目(假设订购两种商品)
INSERT INTO 订单项目 (订单ID, 产品ID, 数量, 单价)
SELECT @OrderID, 产品ID, 1, 价格
FROM 商品
WHERE 产品ID IN (101, 102);

-- 更新订单总价
UPDATE 订单
SET 总价 = (SELECT SUM(数量 * 单价) FROM 订单项目 WHERE 订单ID = @OrderID)
WHERE 订单ID = @OrderID;

SET @TotalAmount = (SELECT 总价 FROM 订单 WHERE 订单ID = @OrderID);

-- 检查并更新库存
IF EXISTS (
SELECT 1
FROM 商品 p
JOIN 订单项目 oi ON p.产品ID = oi.产品ID
WHERE oi.订单ID = @OrderID AND p.库存 < oi.数量
)
BEGIN
ROLLBACK;
RAISERROR('库存不足', 16, 1);
RETURN;
END

UPDATE 商品
SET 库存 = 库存 - oi.数量
FROM 商品 p
JOIN 订单项目 oi ON p.产品ID = oi.产品ID
WHERE oi.订单ID = @OrderID;

-- 检查并更新用户余额
IF (SELECT 余额 FROM 用户 WHERE 用户ID = @UserID) < @TotalAmount
BEGIN
ROLLBACK;
RAISERROR('用户余额不足', 16, 1);
RETURN;
END

UPDATE 用户
SET 余额 = 余额 - @TotalAmount
WHERE 用户ID = @UserID;

-- 更新订单状态
UPDATE 订单
SET 状态 = '已完成'
WHERE 订单ID = @OrderID;

COMMIT;

这个事务执行以下操作:

  1. 创建新订单
  2. 添加订单项目
  3. 计算并更新订单总价
  4. 检查并更新商品库存
  5. 检查并扣除用户余额
  6. 更新订单状态为已完成

如果在过程中出现任何错误(如库存不足或用户余额不足),整个事务将回滚,确保数据库保持一致状态。


评论