【问题标题】:How to avoid 'Transaction managed block ended with pending COMMIT/ROLLBACK' error across methods如何避免跨方法的“事务管理块以挂起的 COMMIT/ROLLBACK 结束”错误
【发布时间】:2011-10-06 16:26:09
【问题描述】:

我有一种情况,我将@transaction.commit_manually 装饰器应用于我正在导入在 http 请求响应中传回的信息的方法。我需要根据业务验证规则是通过还是失败来控制提交和回滚。

现在,当我遇到某种验证失败时,我有一个单独的方法可以将错误记录到数据库中。此操作应始终立即提交,同时将主事务保持在当前状态。但是,如果我将 @transaction.commit_on_success 装饰器应用于错误捕获例程,我的主要事务也会自动提交。如果我不应用 @transaction.commit_on_success 装饰器,那么一旦调用错误捕获例程,我就会收到“事务托管块以挂起的 COMMIT/ROLLBACK 结束”错误。

我正在使用 MYSQL 数据库版本 5.1.49,使用存储引擎 INNODB。

有没有办法在第二个例程中提交事务时,在调用例程中保留打开的事务?

【问题讨论】:

    标签: mysql django transactions


    【解决方案1】:

    Django 的默认事务管理不支持嵌套事务。一般来说,事务不能嵌套。在事务中完成的所有事情要么提交要么回滚。所以当你提交事务时,无论你在哪里提交事务,它都是原子的。

    在网上四处寻找,我找到了一个snippet,这对你来说可能是一个很好的起点。它本质上覆盖了commit_on_success 装饰器,添加了一种引用计数形式。从某种意义上说,如果不是最后一次退出,它就会放弃承诺。

    【讨论】:

    • 感谢您的回答。到目前为止,我对 Django 框架很满意(这是我第一次使用它),但是,鉴于我使用 .NET 能够做到的事情,管理数据库事务方面缺乏灵活性似乎是我的一个缺点框架。至少看起来应该能够将单个“事务”对象传递给不同的类或方法。
    • 是的,但是,根据文档,并通过我自己的测试验证,保存点似乎不适用于 MySQL INNODB 数据库(至少在 Django 1.2.5 下)
    猜你喜欢
    • 1970-01-01
    • 2011-10-25
    • 2012-04-14
    • 2016-06-23
    • 2020-05-23
    • 2016-10-04
    • 1970-01-01
    • 2017-05-19
    • 2010-12-15
    相关资源
    最近更新 更多