1

現在、テーブルにデータを挿入しようとするトランザクションがあります。データが既にテーブルにある場合、制約失敗エラーが発生し、選択が実行されて ID が取得されます。

t2.executeSql('INSERT INTO books (book) VALUES (?);',
  [record],
  function (t2, r) {        // SQL_successfulCallback
    record = r.insertId;
  },
  function (t2, err) {      // SQL_errorCallback
    if (err.message !== 'constraint failed') { // insert failed because of other
                                               // reason - fail transaction
      console.log('Insert SQL error ' + err.code + ' - ' + err.message + '.');
      return true;
    } else { // insert failed because data was already in the table
      t2.executeSql('SELECT bookID FROM books WHERE book=?',
        [record],
        function (t, r) {   // SQL_successfulCallback
          record = r.rows.item(0).classificationID;
        },
        function (t, err) { // SQL_errorCallback
          console.log('Lookup SQL error ' + err.code + ' - ' + err.message + '.');
          return true;
        }
      );
      return false;
    }
  }
);

トランザクションを高速化したいので、最初にデータがテーブルにあるかどうかを確認すると思いました。そうでない場合は、挿入します...

t2.executeSql('SELECT bookID FROM books WHERE book=?',
  [record],
  function (t2, r) {          // SQL_successfulCallback
    if (r.rows.length !== 0) {
      record = r.rows.item(0).bookID;
    } else {
      t2.executeSql('INSERT INTO books (book) VALUES (?);',
        [record],
        function(t2, r){      // SQL_successfulCallbac
          record = r.insertId;
        },
        function (t2, err) {  // SQL_errorCallback
          if (err.message !== 'constraint failed') { // insert failed because of other
                                                     // reason - fail transaction
            console.log('Insert SQL error ' + err.code + ' - ' + err.message + '.');
            return true;
          } else { // insert failed because data was already in the table
            return false;
          }
        }
      );
    }
  },
  function (t, err) {         // SQL_errorCallback
    console.log('Lookup SQL error ' + err.code + ' - ' + err.message + '.');
    return true;
  }
);

...しかし、うまくいきません。このトランザクションは、すべての選択を実行してから挿入を行います。2番目の方法を機能させるにはどうすればよいですか?

4

1 に答える 1

0

トランザクションがリクエストをキューに入れていると仮定しています。したがって、キューは次のようになります

1を選択

2を選択

3を選択

次に、最初の呼び出しの後、トランザクションをコミットすると、次のようになります。

2を選択

3を選択

挿入 1

挿入 2

インサート 3

これは、選択が実行された後に挿入を呼び出す関数が実行され、トランザクションがコミットされるまで発生しないが、選択が既に登録されているために発生します。

そうなるためには

選択1

挿入1

select2

挿入2

select ステートメントごとに個別のトランザクションを作成します。

于 2011-10-31T03:26:51.057 に答える