2016-10-28 2 views
1

のIndexedDB:この行でTransactionInactiveError

var request = store.add(obj); 

私はエラーを取得する:私はAJAXを使用する場合

TransactionInactiveError: A request was placed against a transaction which is currently not active, or which is finished.

私はエラーを取得します。トランザクションが終了する前にAJAXが完了するようにするにはどうすればよいですか?私はオブジェクトストアにSQLデータベースから情報をロードしようとしています。私がこのエラーを捜したとき、私はトランザクションと非同期性についての情報を得るが、私はコードで具体的な解決策を見いださなかった。

私はコールバック、約束事、およびタイムアウト(私にはハックのように感じます)を調べましたが、私はこの非同期呼び出しを動作させることはできません。どんな助けでも大歓迎です。

var req = indexedDB.open(DB_NAME, DB_VERSION); 
req.onsuccess = function() { 
     db = this.result; 
     var tx = db.transaction('tblFields', 'readwrite'); 
     var store = tx.objectStore('tblFields'); 

      $.ajax({ 
        type: "POST", 
        url: "Off.aspx/GetFields", 
        data: '{}', 
        contentType: "application/json; charset=utf-8", 
        dataType: "json", 
        success: function (response) { 
         var customers = response.d; 
         $(customers).each(function() { 
          var obj = { measureID: this.measureID, measureName: this.measureName, fieldName: this.fieldName }; 
          var request = store.add(obj); 
         }); 
        }, 
        failure: function (response) { 
         alert(response.d); 
        }, 
        error: function (response) { 
         alert(response.d); 
        } 
       }); 
} 

答えて

1

成功コールバックは非同期で実行されています。コールバックにトランザクションの初期化コードを移動すると、問題を解決する必要があります。

success: function (response) { 
    var customers = response.d; 
    var tx = db.transaction('tblFields', 'readwrite'); 
    var store = tx.objectStore('tblFields'); 
    $(customers).each(function() { 
     var obj = { measureID: this.measureID, measureName: this.measureName, fieldName: this.fieldName }; 
     var request = store.add(obj); 
    }); 
}, 
0

のIndexedDBは、それは時間の短い期間の後に閉じたトランザクションにはアクティブな要求を検出しない場合。 Ajaxリクエストを作成すると、すぐには応答が得られません。 ajaxリクエストを作成して応答を得るまでの間に、idbはトランザクションを使用しているアクティブなidb要求を認識しないので、トランザクションを閉じます。

解決策は簡単です。最初にajaxリクエストを行い、次にidbトランザクションを実行します。ここではいくつかの擬似コードは次のとおりです。

function dbconnect(name, version, upgrade) { 
    return new Promise(function(resolve, reject) { 
    var request = indexedDB.open(name, version); 
    request.onupgradeneeded = upgrade; 
    request.onsuccess = function(event) { 
     var db = event.target.result; 
     resolve(db); 
    }; 
    request.onerror = function(event) { 
     var error = event.target.error; 
     reject(error); 
    }; 
    request.onblocked = function(event) { 
     console.warn('blocked, not fulfilling promise until unblocked'); 
    }; 
    }); 
} 

function ajaxpostrequest(url) { 
    return new Promise(function(resolve, reject) { 
    $.ajax({ 
     type: 'post', 
     data: '{}', 
     contentType: 'application/json; charset=utf-8', 
     dataType: 'json', 
     url: url, 
     success: resolve, 
     failure: reject, 
     error: reject 
    }); 
    }); 
} 

function addcustomer(db, customer) { 
    return new Promise(function(resolve, reject) { 
    var tx = db.transaction(...); 
    var store = tx.objectStore(...); 
    var obj = {measureId: customer.measureId, ...}; 
    var request = store.add(obj); 
    request.onsuccess = function(event) { 
     resolve(); 
    }; 
    request.onerror = function(event) { 
     reject(event.target.error); 
    }; 
    }); 
} 


async function request_then_connect_then_put() { 
    try { 
    var response = await fetch(url, {method:'post'}); 
    console.log('fetched url'); 
    var json = await response.json(); 
    var customers = json.d; 
    console.log('read json object from text of url'); 
    var db = await dbconnect(...); 
    console.log('connected to database', db.name); 
    var addpromises = customers.map((customer) => addcustomer(db, customer)); 
    var result = await Promise.all(addpromises); 
    console.log('stored all customer object things'); 
    } catch(error) { 
    console.debug(error); 
    } 
} 
:あなたが約束を使用し、ES6へのアクセスを持って、このような何かをしたい場合は

$.ajax({ 
    success: function(response) { 
    var req = indexedDB.open(...); 
    req.onsuccess = function(event) { 
     var db = event.target.result; // or this.result, or req.result 
     var tx = db.transaction(...); 
     var store = tx.objectStore(...); 
     for(var customer of response.d) { 
     var obj = {...}; 
     store.add(obj); 
     } 
    }; 
    } 
});