【问题标题】:Is there any way to commit part of a transaction?有没有办法提交交易的一部分?
【发布时间】:2014-08-19 09:50:31
【问题描述】:

有一个函数A,它启动一个事务,做一些工作,然后调用函数B,做更多的工作,然后提交事务。 A 还会捕获任何异常,这些异常会触发回滚而不是提交。

我的问题是,如果 B 遇到错误,我想将该错误记录到我的数据库中,然后阻止 A 中的事务提交。有没有办法做到这一点?我不能只让 B 调用回滚,因为 B 可能被 A 以外的其他函数使用,它们可能会以不同的方式处理异常。所以B还是需要抛出异常,触发回滚。但是,这会清除我刚刚创建的数据库日志条目。那么,有没有办法让函数在事务中间提交单个插入,同时允许事务的其余部分回滚?

供参考:我在带有 InnoDB 表的 MySQL 数据库上使用 Eloquent ORM 在 PHP 中执行此操作。我直接使用原始 SQL 命令没有任何问题,但我不想切换到不同的表类型。

【问题讨论】:

  • 。 .记录结果是使用事务的祸根——回滚也会撤消记录。在某些情况下,我使用外部文件来记录日志,但我不确定如何在 MySQL 中执行此操作。

标签: mysql sql transactions


【解决方案1】:

如果您想跟踪任何特定错误,可以使用handlers。但我不认为只提交事务的一部分是一个很好的主意。

您也可以查看signal

【讨论】:

  • 这很有趣,我不知道信号,但我不明白它是如何相关的?
【解决方案2】:

您可以将日志发送到 MyISAM 表(因为 MyISAM tables do not support transactionsCOMMITROLLBACK 等对它们没有影响)。

[编辑]
...但我刚刚注意到你写的部分:“我不想切换到不同的表格类型”。 As 3m1n4 suggests,不可能提交事务的任意部分*。我能想到的唯一解决方法是从不同的事务填充日志表。

*可以通过使用save points 部分回滚事务,但我认为这与您的问题无关

【讨论】:

    【解决方案3】:

    关系数据库的首要原则之一是 ACID(原子性、一致性、隔离性、持久性)。 我认为原子性解释了很多你在问什么。原子性确保事务总是全有或全无。这意味着如果事务的一部分失败,整个事务将被回滚,并且 DB 保持不变的状态。

    INSERT、UPDATE 和 DELETE 是自动提交的声明,但如果您将它们作为事务的一部分,则可以覆盖此行为。在 mySql 中是 START TRANSACTION 语句,整个事务在最后提交。 请参阅此链接以获取更多说明:

    http://dev.mysql.com/doc/refman/5.6/en/commit.html

    也是一个很好的问答: https://dba.stackexchange.com/questions/4252/do-inserts-get-auto-committed

    【讨论】:

    • 那么,你是说没有办法做到这一点?
    • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
    • RandomSeed 谢谢,我已经编辑了我的答案。你对 MyISAM 表的回答非常好。我只回答了 InnoDB。
    • 为什么是-1?如果我的回答没有帮助,请说,我会删除它!
    • 我认为你的回答不是没用的(我没有否决它)所以你不一定要删除它,但同时它并没有真正解决我的问题 - 它只是一般背景信息,而不是具体的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-11
    • 1970-01-01
    相关资源
    最近更新 更多