-1

次のような形式で、(適切な 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;
}

この方法により、トランザクションが失敗した場合に、データベースが正しい状態に復元されることが保証されます。

しかし、問題は、トランザクションを実行するときに、そのトランザクションに加えて、別のデータベースを更新する必要があるとしましょう (たとえば、databaseA の列のエントリを更新する場合、databaseB の列の別のエントリを更新する必要があります)。更新しました)。このケースをどのように処理しますか?

たとえば、これが私のコードで、更新が必要な 3 つのデータベース (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 (またはデータベース呼び出しを提供する最低限の言語) を使用しています。したがって、私の解決策はこれを処理する必要があります。

何か案が?

4

3 に答える 3

1

まず、一部のデータベースは、dbA、dbB、および dbC のすべてが一度に同じトランザクションに参加できるようにする分散トランザクション プロトコルをサポートしています。あなたの場合は、それを使用してください:)

ただし、それができない場合は、two-phase-commitPaxosなどの独自の分散トランザクション プロトコルを実装する必要があります。これらのプロトコルは複雑ですが、この複雑さは絶対に必要なので、手を抜こうとしないでください :) このようなものを実装しようとする前に、これらのウィキペディアのリンクからリストされている参考文献に従って読むことをお勧めします。

于 2009-10-23T04:03:55.130 に答える
0

分散トランザクションをサポートする DBMS が必要です。これらはまさに必要なことを行います。複数のシステム間で開始/コミット/ロールバックのセマンティクスを強制します。

たとえば、Enterprise Java Beans と Microsoft Transaction Server は分散トランザクションをサポートしています。

「外部への呼び出し」がデータベースに対するものでない場合は、さらに複雑になります。トランザクションのエミュレートを試みることはできますが、ロールバックが困難 (ファイルシステム操作) または不可能 (サーバーへのデータの投稿) もあります。したがって、それは特定の問題に依存します。

于 2009-10-23T04:03:09.250 に答える
0

ほとんどの RDBMS は分散トランザクションをサポートしています。たとえば、MS SQL Server は分散トランザクション コーディネーター (DTC) というサービスを使用して、分散トランザクションを登録します

于 2009-10-23T04:03:12.480 に答える