事务操作

使用事务保证数据一致性,包括 BEGIN、COMMIT、ROLLBACK 和隔离级别设置

语法

START TRANSACTION | BEGIN;
-- SQL statements
COMMIT | ROLLBACK;
SET TRANSACTION ISOLATION LEVEL level;

参数

参数说明示例级别
BEGIN 开始事务 BEGIN; 常用
COMMIT 提交事务 COMMIT; 常用
ROLLBACK 回滚事务 ROLLBACK; 常用
SAVEPOINT 设置保存点 SAVEPOINT sp1; 进阶
SET TRANSACTION ISOLATION LEVEL 设置隔离级别 SET TRANSACTION ISOLATION LEVEL READ COMMITTED; 进阶

示例

转账事务

BEGIN;

-- 扣减付款方余额
UPDATE accounts SET balance = balance - 500.00
WHERE user_id = 1001 AND balance >= 500.00;

-- 检查是否扣减成功(affected rows = 1)
-- 增加收款方余额
UPDATE accounts SET balance = balance + 500.00
WHERE user_id = 1002;

-- 记录转账流水
INSERT INTO transfer_logs (from_user, to_user, amount, created_at)
VALUES (1001, 1002, 500.00, NOW());

COMMIT;
转账必须用事务,保证扣款和加款要么都成功要么都失败

下单扣库存事务

BEGIN;

-- 扣减库存(用 WHERE stock >= quantity 防止超卖)
UPDATE products SET stock = stock - 1
WHERE id = 2001 AND stock >= 1;

-- 检查 affected_rows,如果为 0 说明库存不足
-- 创建订单
INSERT INTO orders (order_no, user_id, product_id, total_amount, status)
VALUES ('ORD20260523001', 1001, 2001, 5999.00, 0);

COMMIT;
-- 如果任何步骤失败则 ROLLBACK;
电商下单核心逻辑,防止超卖

使用 SAVEPOINT

BEGIN;

INSERT INTO orders (order_no, user_id, total_amount)
VALUES ('ORD001', 1001, 100.00);

SAVEPOINT before_items;

INSERT INTO order_items (order_id, product_id, quantity)
VALUES (LAST_INSERT_ID(), 2001, 2);

-- 如果订单项有问题,只回滚到保存点
ROLLBACK TO before_items;

-- 订单主记录保留
COMMIT;
SAVEPOINT 允许部分回滚,不需要全部重来

查看和设置隔离级别

-- 查看当前隔离级别
SELECT @@transaction_isolation;

-- 设置会话隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

-- 隔离级别从低到高:
-- READ UNCOMMITTED(脏读)
-- READ COMMITTED(不可重复读)
-- REPEATABLE READ(MySQL 默认,幻读)
-- SERIALIZABLE(最严格,性能最差)
大多数互联网应用用 READ COMMITTED 即可

常见错误

ERROR 1213 (40001): Deadlock found when trying to get lock 两个事务互相等待对方释放锁。重试事务即可,同时优化事务中的 SQL 顺序保持一致
Lock wait timeout exceeded; try restarting transaction 其他事务持锁时间过长。检查是否有慢查询或未提交的事务:SHOW PROCESSLIST;

技巧

相关命令