数据库错误处理:如果您必须调用外部服务并且事务失败怎么办?

发布于 2024-08-09 11:36:09 字数 948 浏览 3 评论 0原文

我们都知道,我们总是可以将数据库调用包装在事务中(无论是否有适当的 ORM),其形式如下:

$con = Propel::getConnection(EventPeer::DATABASE_NAME);
try {
    $con->begin();
    // do your update, save, delete or whatever here.
    $con->commit();
} catch (PropelException $e) {
    $con->rollback();
    throw $e;
}

这种方式可以保证如果事务失败,数据库将恢复到正确的状态。

但问题是,假设当我执行一个事务时,除了该事务之外,我还需要更新另一个数据库(例如,当我更新数据库 A 中的列中的条目时,数据库 B 中的列中的另一个条目必须是已更新)。此案如何处理?

比方说,这是我的代码,我有三个需要更新的数据库(dbA、dbB、dbc):

$con = Propel::getConnection("dbA");
try {
    $con->begin();
    // update to dbA
    // update to dbB
    //update to dbc
    $con->commit();
} catch (PropelException $e) {
    $con->rollback();
    throw $e;
}

如果 dbc 失败,我可以回滚 dbA,但无法回滚 dbb。

我认为这个问题应该与数据库无关。由于我使用的是 ORM,因此这也应该是独立于 ORM 的。

更新:一些数据库事务封装在 ORM 中,一些使用裸 PDO、oledb(或任何提供数据库调用的最低语言)。所以我的解决方案必须解决这个问题。

有什么想法吗?

We all know that we can always wrap our database call in transaction ( with or without a proper ORM), in a form like this:

$con = Propel::getConnection(EventPeer::DATABASE_NAME);
try {
    $con->begin();
    // do your update, save, delete or whatever here.
    $con->commit();
} catch (PropelException $e) {
    $con->rollback();
    throw $e;
}

This way would guarantee that if the transaction fails, the database is restored to the correct status.

But the problem is that let's say when I do a transaction, in addition to that transaction, I need to update another database ( an example would be when I update an entry in a column in databaseA, another entry in a column in databaseB must be updated). How to handle this case?

Let's say, this is my code, I have three databases that need to be updated ( dbA, dbB, dbc):

$con = Propel::getConnection("dbA");
try {
    $con->begin();
    // update to dbA
    // update to dbB
    //update to dbc
    $con->commit();
} catch (PropelException $e) {
    $con->rollback();
    throw $e;
}

If dbc fails, I can rollback the dbA but I can't rollback dbb.

I think this problem should be database independent. And since I am using ORM, this should be ORM independent as well.

Update: Some of the database transactions are wrapped in ORM, some are using naked PDO, oledb ( or whatever bare minimum language provided database calls). So my solution has to take care this.

Any idea?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

猫九 2024-08-16 11:36:09

首先,一些数据库支持分布式事务协议,允许所有 dbA、dbB 和 dbC 同时参与同一事务。如果您这样做,请使用它:)

但是,如果做不到这一点,您将需要实现自己的分布式事务协议,例如 两阶段提交Paxos。这些协议很复杂,但这种复杂性绝对必要,所以不要试图走捷径:)我建议遵循这些维基百科链接中列出的参考文献,并在尝试实现类似的东西之前阅读它们这。

First, some databases support distributed transaction protocols that will allow all of dbA, dbB, and dbC to participate in the same transaction at once. If yours does, use that :)

Failing that, however, you will need to implement your own distributed transaction protocol, such as two-phase-commit or Paxos. These protocols are complex, but this complexity is absolutely necessary, so don't be tempted to cut corners :) I would recommend following the references listed from those wikipedia links and reading them before attempting to implement something like this.

层林尽染 2024-08-16 11:36:09

您需要一个支持分布式事务的 DBMS。它们完全满足您的需要:它们在多个系统之间强制执行开始/提交/回滚语义。

例如,Enterprise Java Beans 和 Microsoft Transaction Server 支持分布式事务。

如果“外部调用”不是针对数据库,那就会变得更加棘手。您可以尝试模拟事务,但有些事情很难回滚(文件系统操作)或不可能(将数据发布到服务器)。所以这取决于具体问题。

You need a DBMS that supports Distributed transactions. These do exactly what you need: they enforce the begin/commit/rollback semantics across multiple systems.

For example, Enterprise Java Beans and Microsoft Transaction Server support distributed transactions.

If the "call outside" is not to a database, it gets even trickier. You could try to emulate transactions, but some things are difficult to roll back (filesystem operations) or impossible (posting data to a server). So it will depend on the specific problem.

何止钟意 2024-08-16 11:36:09

大多数 RDBMS 支持分布式事务。例如,MS SQL Server 使用分布式事务协调器 (DTC) 服务来登记 分布式事务

Most RDBMS's support distributed transactions. For instance, MS SQL Server uses the Distributed Transaction Cooridinator (DTC), a service, to enlist distributed transactions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文