未捕获的 InvalidStateError:无法在“IDBDatabase”上执行“事务”:版本更改事务正在运行

Posted

技术标签:

【中文标题】未捕获的 InvalidStateError:无法在“IDBDatabase”上执行“事务”:版本更改事务正在运行【英文标题】:Uncaught InvalidStateError: Failed to execute 'transaction' on 'IDBDatabase': A version change transaction is running 【发布时间】:2016-02-16 01:14:45 【问题描述】:

我必须承认我对 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;
      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 很陌生

【问题讨论】:

【参考方案1】:

在尝试加载对象存储之前,您需要检查版本更改事务是否完成:

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】:

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
  ;

您遇到错误是因为您在版本更改事务仍在运行时尝试启动第二个事务。

【讨论】:

但是如何指定事务的跨度? 它给我一个错误Uncaught NotFoundError: Failed to execute 'objectStore' on 'IDBTransaction': The specified object store was not found.在线`transaction.objectStore('text')`【参考方案3】:

在版本更改中,您不需要指定事务的范围。这始终是所有预设对象存储。 transaction.objectStore('text') 在这里你试图打开一个带有索引名称的对象存储,这是行不通的。如果你想访问索引,你需要先去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)

试试这个

【讨论】:

以上是关于未捕获的 InvalidStateError:无法在“IDBDatabase”上执行“事务”:版本更改事务正在运行的主要内容,如果未能解决你的问题,请参考以下文章

未捕获的 InvalidStateError:无法在“IDBDatabase”上执行“事务”:版本更改事务正在运行

Java Server,html客户端,无法向服务器发送消息

未捕获的类型错误:无法读取未定义的属性“区域”?

如何在应用程序加载期间捕获“未捕获的类型错误:无法读取未定义的属性‘isModel’?

未捕获的类型错误:无法读取未定义的属性 toLowerCase

错误:`未捕获(承诺中)类型错误:无法读取未定义的属性'doc'`