跳到正文

事务

Transaction

高级通用

事务(Transaction)是数据库把一组操作作为一个整体处理的机制:全部成功才提交,出错则回滚未提交的修改。它解决多步写入只完成一部分造成的数据不一致问题,例如创建订单时,不能只扣库存却没生成订单。

你可能会说:「帮我把创建订单和扣减库存绑在一起,别出现库存扣了却没有订单的情况。」

读之前建议先了解(这是一个高级概念)

动手看看

开始事务下单应用事务进行中库存记录订单记录
1

用户提交订单后,应用先开启事务。扣库存和建订单会被当成一组操作处理。

要点

  1. 1

    先划定哪些操作算一组

    假设你做一个商店后台,创建订单和扣减库存都写在同一个数据库里。如果这两步代表同一次购买,我们就把它们放进一个事务,而不是各自执行完就算成功。

  2. 2

    提交前失败就一起回滚

    事务中的操作都成功后,数据库才提交这组修改。如果中途报错,事务可以回滚未提交的修改,这样就不会留下“库存扣了、订单却没建成”的半成品。

  3. 3

    并发时仍要检查业务条件

    事务不等于自动解决超卖。两个人同时购买最后一件商品时,你还得让扣库存的语句检查剩余数量,并确认实际扣减成功;事务负责让这次检查后的相关写入一起完成或一起撤销。

容易混淆的地方

事务和锁不是一回事:事务定义哪些数据库操作一起提交或回滚,锁用于协调并发访问。事务也不是通用的“撤销按钮”:提交后不能靠回滚撤销;发邮件、调用支付接口等外部动作,通常也不会随数据库事务自动回滚。

什么时候用

适合用

  • 用户下单时,订单记录与库存扣减必须一起成功,否则页面会展示不存在或无法履约的订单。
  • 后台转移账户余额时,扣出方与增加方的记录都存在同一个数据库,需要避免只完成一边。
  • AI 工具创建对话时,要同时写入对话记录和首条消息,任何一步失败都不留下残缺对话。

不适合用

  • 只是切换前端标签页、展开面板或编辑尚未保存的输入内容,不涉及数据库写入,用界面状态管理就够了。
  • 只是调用第三方发邮件,数据库事务管不到邮件服务;改用任务队列,并设计失败重试。
  • 几条互不依赖的访问日志各自写入,没必要硬放进一个显式事务;按需逐条写入或批量写入即可。

练一练

你在做下单接口:订单和库存存在同一个数据库,下单成功后还要给用户发邮件。怎样安排更合适?

让 AI 帮你做

请检查下单接口,把创建订单与扣减库存放进同一个数据库事务;扣库存时确认库存足够且实际扣减成功,任一步失败就回滚。事务提交成功后再安排发邮件,并说明邮件失败如何重试。

接下来学什么