pg-promise事务中执行非SQL函数失败时,事务会回滚吗?
关于pg-promise事务回滚与外部服务调用的问题
业务场景:需要在用户从数据库删除后,同步将其从外部服务移除,任一操作失败则整个删除操作需撤销。拟采用以下代码实现:
const removeUser = async (user) => { await db.tx(async tx => { await removeUserFromDB(tx, user) await removeUserFromExternalService(user) }) }
问题
请问当调用未使用tx上下文的外部服务失败时,pg-promise的事务回滚机制是否依然生效?即回调内任一操作失败时事务都应回滚。
解答
这个回滚机制是生效的。
pg-promise的事务规则很明确:只要db.tx传入的异步回调函数抛出异常,或者返回的Promise被拒绝,整个事务就会自动触发回滚。
放到你的代码逻辑里看:
- 第一步
removeUserFromDB(tx, user)在事务上下文里执行,成功后才会执行下一步; - 如果后续
removeUserFromExternalService(user)调用失败(不管是抛出错误还是Promise被拒绝),整个回调函数就会进入失败状态,pg-promise会自动回滚之前在数据库里完成的删除操作。
但要注意一个核心局限:外部服务的操作是无法被回滚的。举个例子:如果数据库删除成功,外部服务的删除请求也已经执行完成,但后续因为某种原因(比如网络波动导致外部服务返回失败响应),此时数据库的操作会被回滚,但外部服务里的用户已经被删掉了——这种“单边成功”的情况是本地事务解决不了的。如果要处理这种分布式场景,你需要额外设计补偿机制,或者用消息队列来保证最终一致性。
内容的提问来源于stack exchange,提问作者zaplec
相关产品推荐
相关产品推荐

