你在银行App里转账,点下“确认”后手机卡了一下——页面没跳转,也没提示成功。你慌了:钱到底扣了没?转出去没?这时候,背后起作用的,就是事务的提交(Commit)和回滚(Rollback)。
事务不是功能,是保障
事务不是某个按钮或菜单项,而是数据库执行一组操作时的“原子性约定”:要么全部成功,要么全部作废。就像发快递,打包、贴单、出库、发货——中间任何一环出错,整单就得退回重来,不能只发一半包裹。
提交:盖章生效
当你执行完增删改操作,数据库不会立刻写死硬盘。它先记在内存和日志里,等你明确说“没问题,保存”,才真正落盘。这个动作就叫 提交:
BEGIN TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE user_id = 1001;
UPDATE accounts SET balance = balance + 100 WHERE user_id = 1002;
COMMIT; <!-- 此刻两笔账才正式生效 -->一旦 COMMIT 执行成功,数据就不可逆地写入,哪怕服务器突然断电,重启后也能从日志里恢复这一状态。
回滚:一键撤回
但如果第二条 UPDATE 因余额不足失败了呢?前一条已经扣了100块,不处理就会导致数据错乱。这时,数据库自动触发 回滚:
BEGIN TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE user_id = 1001;
UPDATE accounts SET balance = balance + 100 WHERE user_id = 1002; <!-- 假设这里报错:余额不足 -->
ROLLBACK; <!-- 所有已执行的操作全部撤销,账户回到原始状态 -->回滚不是“撤销上一步”,而是把整个事务像倒带一样清空——就像你填完三页报名表,最后发现身份证号填错了,直接撕掉重来,而不是只改第三页。
日常里,它们藏在哪?
微信红包发到一半闪退?订单支付后页面白屏?后台系统早就在你没察觉时悄悄启用了事务控制。电商下单要扣库存、生订单、记日志、通知物流——五六个操作必须捆在一起执行;只要其中一环失败(比如库存被秒光),整个流程立刻回滚,你看到的就是“下单失败,请重试”,而不是“订单生成了但库存没减”。
开发写代码时,常会用 try-catch 包住数据库操作:成功就 commit,异常就 rollback。用户看不见这些逻辑,但每一次“稳稳当当”的操作体验,背后都是事务在默默兜底。