7

Safari Client-Side Storage and Offline Applications Programming Guideに記載されているように、HTML 5 Web SQL データベース トランザクションのロールバックは、トランザクション メソッドへのエラー コールバックとして提供されるコールバック関数で true を返すことによって行われますexecuteSql

クエリごとのエラー処理コールバックはかなり単純です。コールバックが true を返す場合、トランザクション全体がロールバックされます。コールバックが false を返した場合、トランザクションは何も問題がなかったかのように続行されます。したがって、オプションのクエリを実行している場合 (その特定のクエリの失敗によってトランザクションが失敗するべきでない場合)、false を返すコールバックを渡す必要があります。クエリの失敗によってトランザクション全体が失敗する場合は、true を返すコールバックを渡す必要があります。

たとえば、次のトランザクションがある場合 (「users」テーブルの「username」フィールドに UNIQUE 制約があり、ユーザー名「test」が既に存在するとします。これを再度挿入しようとすると、制約エラーが発生するはずです) :

database.transaction(function(transaction) {
    transaction.executeSql(
        "INSERT INTO users (username) VALUES('test')",
        null,
        dataCallback,
        errorCallback
     );
});

function errorCallback() {
    return true; //this causes the rollback
}

2 つの質問があります。

  1. トランザクション内に多くの操作を含める必要があり (たとえば、ajax を使用してサーバーにデータを送信し、応答を待つ必要があるなど)、応答が到着する前にユーザーがページをリロードした場合 (つまり、errorCallback呼び出されません)、トランザクションはコミットされますか、それとも失敗しますか?

  2. Web SQL トランザクションを手動でロールバックする方法を知っている人はいますか? たとえば、ajax 呼び出しの結果に基づいてトランザクションをロールバックしたい場合、どのように行うことができますか? エラー コールバックが確実に呼び出されるようにするには、エラーを含むクエリを実行する必要がありますか?

ありがとう。

4

2 に答える 2

2
  1. トランザクションがコミットされます。
  2. はい、明示的にロールバックするには、無効なクエリを明示的に呼び出す必要があります。abortクイック アンド ダーティ API にはメソッドがないため、これは推奨される回避策です。

AJAXに関しては、書き込みトランザクションを開始する前に、すべてのデータを準備してください。おっしゃる通り問題ないでしょう。データベース制約 (UNIQUE、FOREIGNKEY) を可能な限り使用します。

于 2013-04-05T02:52:50.147 に答える
1

トランザクション中に AJAX 呼び出しを行う方法を見つけましたか? 仕様全体を読み終えていませんが、これまでのところ、SQLTransactionCallbackorSQLTransactionSyncCallbackが返されると、トランザクションにそれ以上のものを追加できないようです。おそらく結果のコールバックからですか?

編集:もう一度見てみると、仕様(リンク先のAppleドキュメントよりもはるかに少ないエラーが含まれていますが、読みにくいです)は次のように述べています

  1. 、、またはの実行中にメソッド [ executeSql] が呼び出されなかった場合、例外が発生します。SQLTransactionCallbackSQLStatementCallbackSQLStatementErrorCallbackINVALID_STATE_ERR

だから仕方がないということだと思います。

さらに編集:いいえ、待ってください!SQLStatementCallbackが呼び出されるまでに時間がかかる限り、前の のステートメント コールバックから毎回、AJAX 呼び出しによって必要なデータがある場所にフラグが設定されるまで、何度も何度もビジー待機を行うことができます。これはひどいプログラミングです (正当な理由もなく大量の CPU を消費し、ページの再表示などの優先度の低いタスクをブロックする可能性があります) が、任意の期間トランザクションを開いたままにしておく唯一の方法だと思います。残念ながら、SQLite ではできません。select 3 + 4select 3 + 4select 3 + 4, sleep(1)

一般に、SQLite (ここでは基盤となるストレージ エンジン) は未完了のトランザクションをロールバックします。あなたが尋ねているページの再読み込みエラーのケースはまだテストしていません。それがコミットされていたら、私は非常に驚くでしょう。

ところで、この質問を投稿していただきありがとうございます。元の仕様で細心の注意を払って文書化されているにもかかわらず、トランザクションをロールバックする方法を見つけようとしていました。

于 2011-03-16T21:13:30.047 に答える