【问题标题】:Example of a transaction in MongoDB 4.0 using PHPMongoDB 4.0 中使用 PHP 的事务示例
【发布时间】:2018-11-29 18:40:11
【问题描述】:

我需要在 PHP 中展示使用 mongoDB 的事务。在我的示例中,我有“帐户”和“转账”。第一个操作是我从“汇款人账户”中扣除余额并尝试将钱汇到“收款人账户”,但后者不能接受任何转账,因此交易应该回滚,即资金应该退回到汇款人账户。

我找不到任何关于在线交易的 PHP 特定文档,因此我真的不知道如何去做。

感谢您的帮助!

【问题讨论】:

    标签: php mongodb transactions


    【解决方案1】:

    如果您正在使用包装驱动程序的 PHP 库,则在创建 Client 的实例之后,例如调用$client,您可以执行以下操作:

    $session = $client->startSession();
    $session->startTransaction();
    try {
        // Perform actions.
        $session->commitTransaction();
    } catch(Exception $e) {
        $session->abortTransaction();
    }
    

    不幸的是,经过粗略搜索后,我在PHP library reference 中找不到任何相关文档,但我在PHP library's issues 中找到了一些示例,这些示例表明从客户端创建会话并使用该会话启动然后提交或中止事务是适当的程序。

    不过有几点需要注意:

    如果您查看 MongoDB 文档(如上链接),您会注意到使用副本集的要求并没有特别突出地显示在第三个标题下,并且在所有示例代码之后(如果您像我一样,这将是您首先要寻找的东西)。

    【讨论】:

    • 如果将Transactions转换为副本集stackoverflow.com/questions/60809844/…,也可以在独立服务器上使用stackoverflow.com/questions/60809844/…
    • 在这个例子中需要手动关闭会话吗?
    • @rodigy 如果遇到与数据库相关的异常,最好显式中止事务,特别是如果您的代码将在请求完成处理之前执行其他查询。即使您的特定脚本在出现错误后没有执行额外的数据库查询,通过显式中止事务,您将避免将来在您确实需要执行额外查询的情况下出现任何草率错误。始终养成良好的习惯!
    【解决方案2】:

    根据 mongodb 文档,接受的答案遗漏了一个关键部分 - 您需要将会话作为参数传递给任何应该成为事务一部分的操作。否则,它们只会像正常操作一样运行(即,如果事务中止,则不会回滚) - 它不像传统 RDBMS 的事务,它只是开始事务,之后的所有内容默认情况下都是事务的一部分,直到 COMMIT(或 ROLLBACK) .

    话虽如此,事务在 mongo 中仍然很新,而且我什至无法获得在 mongo 4.0.12 w/PHP MongoDB 驱动程序 1.5.5 下工作的示例 PHP 代码,所以它可能仍然处于最前沿(或者可能只是不使用 mongo 和驱动程序的组合)。

    更新:看来您需要一个副本集,而不是独立服务器,才能在 mongodb 中使用事务。

    更新:已接受的答案直接编辑以包含此信息

    【讨论】:

    • 您在这里提出了一些非常重要的观点。运行副本集的要求即使在深入研究文档后也不是很明显,因为似乎他们将其视为给定的并且并没有真正强调它。请随时直接编辑我的答案以包含这些附加信息。我很高兴看到编辑使我的答案更加准确和有用!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-26
    • 2011-02-12
    • 2018-11-23
    相关资源
    最近更新 更多