18

複数のトランザクション (テーブルの読み取り、テーブルへの書き込み、別のテーブルへの書き込みなど) を開く代わりに、適切な IDBTransaction を使用している限り、単一のトランザクションからすべてを実行できますか?

Mozilla は次のように述べています。「トランザクションをアクティブに保つ唯一の方法は、トランザクションに対してリクエストを行うことです。リクエストが完了すると、DOM イベントが発生し、リクエストが成功したと仮定すると、トランザクションを延長する別の機会が得られます。そのコールバック中に。」これは少しあいまいです。DOM コールバックのイベント ハンドラーを提供すれば、そのコールバック内の任意の時点で、トランザクションが閉じられることを心配することなくトランザクションを使用できるということですか?

https://developer.mozilla.org/en/IndexedDB/Using_IndexedDB#Adding_data_to_the_database

4

4 に答える 4

35

簡単な答え: 「成功」または「エラー」イベントのイベント ハンドラーを提供する場合、そのイベント ハンドラー内に新しい要求を配置でき、トランザクションが自動的に閉じられることを心配する必要はありません。

長い答え: 通常、トランザクションのコミットは完全に透過的であるべきです。唯一のルールは、データベース以外の「作業」を行っている間はトランザクションを開いたままにすることはできないということです。つまり、トランザクションを開始してから、XMLHttpRequest を実行している間、またはユーザーがボタンをクリックするのを待っている間、トランザクションを開いたままにすることはできません。

トランザクションに対するリクエストの送信を停止し、最後のリクエスト コールバックが終了するとすぐに、トランザクションは自動的に閉じられます。

ただし、トランザクションを開始し、そのトランザクションを使用してデータを読み取り、結果を書き込むことはできます。

そのため、トランザクションを開始する前に必要なデータがすべて揃っていることを確認してから、要求コールバックで実行したいすべての読み取りと書き込みを行います。取引が完了すると、自動的に取引が終了します。

于 2012-06-15T22:48:09.330 に答える
12

IndexedDB トランザクションは、最後のコールバックが発生するとすぐにコミットされるため、トランザクションを存続させる方法は、コールバックを介してトランザクションを渡すことです。

私は、Mozilla 開発者で IndexedDB の共同仕様ライターである Jonas Sicking からトランザクション情報を入手しています。彼は、この素晴らしいブログ投稿に次のようにコメントしています。

次の文は正しくありません。「今日のトランザクションは、トランザクション変数が範囲外になり、それ以上のリクエストを送信できない場合に自動的にコミットされます」。

変数がスコープ外になると、トランザクションが自動的にコミットされることはありません。通常、最後の成功/エラー コールバックが発生し、そのコールバックがそれ以上のリクエストをスケジュールしない場合にのみコミットします。したがって、変数のスコープには関係ありません。

これに対する唯一の例外は、トランザクションを作成するが、それに対してリクエストを送信しない場合です。その場合、イベント ループに戻るとすぐに、トランザクションは "コミット" されます (要求のないトランザクションの場合は、それが何を意味するにせよ)。このシナリオでは、トランザクションへのすべての参照が範囲外になるとすぐにトランザクションを技術的に「コミット」できますが、最適化するのに特に興味深いユース ケースではありません。

于 2012-05-01T22:19:16.310 に答える
3

簡単な答え: 保持しないでください。

競合状態を防ぐために、IndexedDB は暗黙的なコミット用に設計されているため、明示的にトランザクションを存続させてはなりません。必要な場合は、アルゴリズムを変更して、存続させる必要がないようにします。

パフォーマンスと順序付けられたリクエストの実行のためにトランザクションを再利用します。このような場合、トランザクションは暗黙的に存続します。

于 2013-05-27T07:31:19.107 に答える
0

トランザクションをアクティブに保つには、完了した操作のコールバックから次の操作を実行し続けます。以下のサンプルコードを参照してください。

function put_data(db,tableName,data_array)
{
    var objectStore=db.transaction([tableName],"readwrite").objectStore(tableName);
    put_record(data_array,objectStore,num_rows,0);
}

function put_record(data_array,objectStore,row_index)
{
    if(row_index<data_array.length)
    {
        var req=objectStore.put(data_array[row_index]);
        req.onsuccess=function(e)
        {
            row_index+=1;
            put_record(data_array,objectStore,row_index);
        };
        req.onerror = function()
        {
            console.error("error", this.error);
            row_index+=1;
            put_record(data_array,objectStore,row_index);
        };
    }
}
于 2014-12-20T11:38:27.557 に答える