Django事务中on_commit钩子触发时抛出错误会发生什么?
问题解答:Django on_commit回调抛错是否会回滚事务?
核心结论
事务不会回滚,因为on_commit钩子是在事务成功提交完成后才触发执行的。
详细解释
on_commit的执行时机:Django的
transaction.on_commit()注册的回调函数,只会在当前事务成功提交到数据库(比如你使用的PostgreSQL已经完成commit操作,数据完成持久化)之后才会被调用。也就是说,当回调开始执行时,数据库里的MyModel记录已经被成功保存,事务状态是已提交的。回调抛错的影响:如果
my_oncommit_callback抛出错误,这个异常只会中断当前回调的执行以及后续的代码流程(如果没有捕获的话),但不会改变已经提交的事务状态——数据库里的数据依然是保存后的状态,不会回滚。潜在的业务问题:这种情况会导致业务逻辑不一致,比如你的例子里,数据库记录已经存在,但文件移动操作失败了,但数据库本身的状态是正常的,没有异常。你需要自己处理这种场景,比如捕获回调里的异常做补偿操作,或者设计幂等的后续处理流程。
针对你的代码示例
当你调用MyModel.save()时:
- 首先将
my_oncommit_callback注册到当前事务的提交钩子 - 执行
super().save()把数据写入数据库(此时事务还未提交,除非是自动提交模式) - 当所在事务提交成功后,触发
my_oncommit_callback - 回调抛错,事务已经提交完成,数据库记录保留,异常向上抛出
内容的提问来源于stack exchange,提问作者thclark
相关产品推荐
相关产品推荐

