事务
Transaction
高级通用事务(Transaction)是数据库把一组操作作为一个整体处理的机制:全部成功才提交,出错则回滚未提交的修改。它解决多步写入只完成一部分造成的数据不一致问题,例如创建订单时,不能只扣库存却没生成订单。
你可能会说:「帮我把创建订单和扣减库存绑在一起,别出现库存扣了却没有订单的情况。」
动手看看下单时库存扣了,订单却没建成
1
用户提交订单后,应用先开启事务。扣库存和建订单会被当成一组操作处理。
要点事务怎样保证多步操作一起完成?
- 1
先划定哪些操作算一组
假设你做一个商店后台,创建订单和扣减库存都写在同一个数据库里。如果这两步代表同一次购买,我们就把它们放进一个事务,而不是各自执行完就算成功。
- 2
提交前失败就一起回滚
事务中的操作都成功后,数据库才提交这组修改。如果中途报错,事务可以回滚未提交的修改,这样就不会留下“库存扣了、订单却没建成”的半成品。
- 3
并发时仍要检查业务条件
事务不等于自动解决超卖。两个人同时购买最后一件商品时,你还得让扣库存的语句检查剩余数量,并确认实际扣减成功;事务负责让这次检查后的相关写入一起完成或一起撤销。
容易混淆的地方
事务和锁不是一回事:事务定义哪些数据库操作一起提交或回滚,锁用于协调并发访问。事务也不是通用的“撤销按钮”:提交后不能靠回滚撤销;发邮件、调用支付接口等外部动作,通常也不会随数据库事务自动回滚。
什么时候用
适合用
- 用户下单时,订单记录与库存扣减必须一起成功,否则页面会展示不存在或无法履约的订单。
- 后台转移账户余额时,扣出方与增加方的记录都存在同一个数据库,需要避免只完成一边。
- AI 工具创建对话时,要同时写入对话记录和首条消息,任何一步失败都不留下残缺对话。
不适合用
- 只是切换前端标签页、展开面板或编辑尚未保存的输入内容,不涉及数据库写入,用界面状态管理就够了。
- 只是调用第三方发邮件,数据库事务管不到邮件服务;改用任务队列,并设计失败重试。
- 几条互不依赖的访问日志各自写入,没必要硬放进一个显式事务;按需逐条写入或批量写入即可。
练一练选一个答案,看看解释
你在做下单接口:订单和库存存在同一个数据库,下单成功后还要给用户发邮件。怎样安排更合适?
让 AI 帮你做复制给 AI Agent 直接用
请检查下单接口,把创建订单与扣减库存放进同一个数据库事务;扣库存时确认库存足够且实际扣减成功,任一步失败就回滚。事务提交成功后再安排发邮件,并说明邮件失败如何重试。