web-dev-qa-db-ja.com

Uncaught InvalidStateError:「IDBDatabase」で「transaction」の実行に失敗しました:バージョン変更トランザクションが実行されています

私はindexedDBに非常に慣れていないことを認めなければなりません

indexedDBの簡単なコードを書きましたが、次のとおりです。

function go(){var req = window.indexedDB.open("Uploader", 1), db;
    req.onerror=function(e){console.log('Error')};
    req.onsuccess = function(e){db=e.target.result;};
    req.onupgradeneeded = function(e){console.log(db);
        db=e.target.result;db=e.target.result;
        var os = db.createObjectStore('Files', {keyPath:"files"});
            os.createIndex('text', 'text_file', {unique:false})
        var trans = db.transaction(['text'], "readwrite");  
        var objectstore=  trans.objectStore("text");
        var addreq = objectstore.add('Instructions.js');
            addreq.onsuccess = function(e){console.log('Success!');console.dir(e)}
    }}

それが私に与えているエラーはUncaught InvalidStateError: Failed to execute 'transaction' on 'IDBDatabase': A version change transaction is running.です

A version change Transaction is runningと言っていますが、私が調べた限りでは、バージョン変更トランザクションはIDBFactory.openメソッドから行われ、使用したことはなく、このトランザクションがreadwriteであることを指定しました。このトランザクションはonupgradeneededにありますが、なぜエラーが発生するのでしょうか。

私はindexedDBに非常に慣れていないことを認めなければなりません

7
anni saini

オブジェクトストアをロードする前に、バージョン変更トランザクションの完了を確認する必要があります。

request.onupgradeneeded =
    function(event) {
        db = event.target.result;
        var store = db.createObjectStore('Files', {keyPath:"files"});
        var transaction = event.target.transaction;

        transaction.oncomplete =
            function(event) {    
                // Now store is available to be populated
            }
    }
9
Velojet

Versionchangeトランザクションでは、読み取り/書き込みも可能です。 onupgradeneeded関数内で作成されたトランザクションにアクセスする必要があります。

function go() {
  var req = indexeddb.open(...);
  req.onupgradeneeded = function(event) {

    // note that event.target === req === this, use whatever you like
    var db = event.target.result;

    // createObjectScore implicitly uses the versionchange txn running 
    // here, without telling you, basically a convenience function
    var objectStore = db.createObjectStore(...);

    // the important part that i am describing in this answer, 
    // grab the handle of the versionchange txn 
    // that is already running and was created for you
    // note again that event.target === req, you could just do
    // req.transaction or this.transaction here.
    // note this is a property of the open request, not a method. do NOT
    // confuse this with the method transaction() that is used to create a 
    // new transaction.
    var txn = event.target.transaction;

    // note that txn.objectStore(...) will work here, because the 
    // createObjectStore call earlier guarantees the store exists here
    // within the implicit upgrade txn
    var addRequest = txn.objectStore(...).add('value');

    // side note: if in previous line we did:
    // var objectStoreRetrievedFromTxn = txn.objectStore(...);
    // then that variable is equal to the same variable returned from 
    // db.createObjectStore earlier in this function. Both are simply handles 
    // (references, pointers, whatever you want to call it) to the store.

    // kind of dumb, but you could do this just to log something
    addRequest.onsuccess = function() {console.log('Success!');};
  };

  // called once upgrade txn completes (if it even needed to run), 
  // and db is opened
  req.onsuccess = function(event) {
    console.log('upgrade txn completed and db is now connected');
    // here, create whatever readwrite or readonly txns you want, note these 
    // txns are separate from and different than the versionchange txn from 
    // before, because that is a unique transaction only available within 
    // onupgradeneeded. however, both versionchange and readwrite are similar
    // in that both support calls to put or add
  };
}

バージョン変更トランザクションの実行中に2番目のトランザクションを開始しようとしているため、エラーが発生しています。

8
Josh

バージョン変更では、トランザクションのスコープを指定する必要はありません。これは常にすべてのprensetオブジェクトストアです。 transaction.objectStore('text')ここでは、インデックスの名前でオブジェクトストアを開こうとしていますが、これは機能しません。インデックスにアクセスする場合は、最初にオブジェクトストアにアクセスする必要があります。

データの追加は、オブジェクトストアで行う必要があります。

function go(){var req = window.indexedDB.open("Uploader", 1), db;
req.onerror=function(e){console.log('Error')};
req.onsuccess = function(e){db=e.target.result;};
req.onupgradeneeded = function(e){
    console.log(db);
    db=e.target.result;
    var trans=e.target.transaction;
    var os = db.createObjectStore('Files', {keyPath:"files"});
        os.createIndex('text', 'text_file', {unique:false})
    var objectstore=  trans.objectStore("Files");
    var addreq = objectstore.add('Instructions.js');
        addreq.onsuccess = function(e)  {console.log('Success!');console.dir(e)}
}}

これを試してみてください

1
Kristof Degrave