Uncaught InvalidStateError: Failed to execute 'transaction' on 'IDBDatabase': A version change transaction is running

淺唱寂寞╮ 提交于 2019-12-22 04:42:47

问题


i must admit that i am very new to indexedDB

I wrote a simple code of indexedDB and it is as followed:

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)}
    }}

the error it is giving me is Uncaught InvalidStateError: Failed to execute 'transaction' on 'IDBDatabase': A version change transaction is running.

It is saying that A version change Transaction is running but as far as i have studied, a version change transaction is made from IDBFactory.open method and i haven't used and i have specified that this transaction is readwrite and this transaction is in onupgradeneeded then why there is an error?

i must admit that i am very new to indexedDB


回答1:


You need to check for the completion of the version change transaction before attempting to load the object store:

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
            }
    }



回答2:


The versionchange transaction also allows you to readwrite. You just need to access the transaction created for you within the onupgradeneeded function.

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
  };
}

You are encountering the error because you are trying to start a second transaction while the version change transaction is still running.




回答3:


in a version change you do not need to specify a scope for the transaction. This is always all the prenset object stores. transaction.objectStore('text') here you are trying to open an object store with the name of the index, this isn't going to work. You need to go to the objectstore first if you want to access the index.

Adding data needs to be done on the objectstore.

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)}
}}

Give this a try



来源:https://stackoverflow.com/questions/33709976/uncaught-invalidstateerror-failed-to-execute-transaction-on-idbdatabase-a

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!