Django 事务 : How to run extra code during rollback?

标签 django transactions

假设您的网络应用中有一个 User 模型,并且您需要通过 API 使该用户与外部服务保持同步。因此,当您在本地创建用户时,您还需要远程创建它。

您的所有操作都在 transaction.atomic() 下,并且您尝试将所有第 3 方 API 调用保留在原子 block 之后,这是合理的。

但是,系统就是一个系统,它会变得越来越复杂,直到您在更新调用中删除一些非常难以删除的第 3 方调用。

也就是说,有没有办法扩展 Django 的事务机制,添加一些回调函数,例如 rollback.add_callback(clean_3rdparty_user(user_id=134))

这样我就可以保证采取所有必要的回滚操作并且我的系统保持同步?

最佳答案

Django事务钩子(Hook)代码的作者有this to say关于为什么有 on_commit() 但没有 on_rollback():

A rollback hook is even harder to implement robustly than a commit hook, since a variety of things can cause an implicit rollback. For instance, your database connection was dropped because your process was killed without a chance to shutdown gracefully: your rollback hook will never run.

由于回滚通常是由异常触发的,因此一种简单的方法是捕获任何异常并在那里运行撤消代码。

try:
    with transaction.atomic():
        # Do database stuff
        # Do external stuff
except:
    # We know the database stuff has rolled back, so...
    # Undo external stuff
    raise

这并不是特别优雅。我同意以下来自同一来源的观点:

The solution is simple: instead of doing something during the atomic block (transaction) and then undoing it if the transaction fails, use on_commit to delay doing it in the first place until after the transaction succeeds. It’s a lot easier to undo something you never did in the first place!

但听起来你也同意这一点。

关于Django 事务 : How to run extra code during rollback?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50222974/

相关文章:

java - Oracle - 如何正确执行事务?

sql - catch block 出错后如何继续?

python - related_name 参数在 Django 模型中没有按预期工作?

Django + Postgresql -> 未处理的异常

django按两级外键关系过滤

javascript - a.toLowerCase 将 CORS 添加到 ajax header 时

Django 1.9 - 不显示用户上传的图像

java - @Transactional 和entityManager.persist(o);

java - UserTransaction 和 EntityTransaction 的区别

java - Spring 中有多个事务管理器并在运行时选择一个