Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从多个javascript线程访问IndexedDB_Javascript_Web Worker_Indexeddb - Fatal编程技术网

从多个javascript线程访问IndexedDB

从多个javascript线程访问IndexedDB,javascript,web-worker,indexeddb,Javascript,Web Worker,Indexeddb,概述: 我试图通过从网页和web工作者访问IndexedDB来避免竞争条件 设置: 当用户使用站点时,将项目保存到本地IndexedDB的网页。每当用户将数据保存到本地数据库时,记录被标记为“未发送” Web worker后台线程,从IndexedDB中提取数据,将其发送到服务器,服务器收到数据后,将IndexedDB中的数据标记为“已发送” 问题: 由于对IndexedDB的访问是异步的,我不能保证用户不会在web工作人员将记录发送到服务器的同时更新记录。时间表如下所示: Web worker

概述: 我试图通过从网页和web工作者访问IndexedDB来避免竞争条件

设置: 当用户使用站点时,将项目保存到本地IndexedDB的网页。每当用户将数据保存到本地数据库时,记录被标记为“未发送”

Web worker后台线程,从IndexedDB中提取数据,将其发送到服务器,服务器收到数据后,将IndexedDB中的数据标记为“已发送”

问题: 由于对IndexedDB的访问是异步的,我不能保证用户不会在web工作人员将记录发送到服务器的同时更新记录。时间表如下所示:

  • Web worker从数据库获取数据并将其发送到服务器
  • 传输发生时,用户更新将其保存到数据库的数据
  • web工作者从服务器获取响应,然后将数据库更新为“已发送”
  • 现在数据库中有一些数据尚未发送到服务器,但标记为“已发送”
  • 失败的解决方案: 从服务器得到响应后,我可以重新检查行,查看是否有任何更改。然而,我仍然有一个小窗口,可以将数据写入数据库,并且永远不会发送到服务器

    例如: 服务器表示数据已保存后,然后:

    IndexedDB.HasDataChanged(
        function(changed) { 
            // Since this is async, this changed boolean could be lying.
            // The data might have been updated after I checked and before I was called.
            if (!changed){ 
              IndexedDB.UpdateToSent() }
        });
    
    其他注意事项: 根据W3规范,有一个同步api,但是还没有人实现它,所以不能使用它(http://www.w3.org/TR/IndexedDB/#sync-数据库)。syncapi被设计为供web工作者使用,以避免我假设的这种情况


    如果您对此有任何想法,我们将不胜感激。已经做了大约一周了,还没有找到任何有效的方法。

    你能使用事务吗?

    我想我现在已经找到了解决这个问题的办法。虽然没有我想要的那么干净,但它似乎是线程安全的

    每当我更新数据时,我首先将datetime存储到LastEdit字段中。 从网络工作者那里,我正在向浏览器发布一条消息

    self.postMessage('UpdateDataSent#' + data.ID + '#' + data.LastEdit);
    
    然后在浏览器中,只要上次编辑日期没有更改,我就会更新我的发送标志

    // Get the data from the DB in a transaction
    if (data.LastEdit == lastEdit)
    {
        data.Sent = true;
        var saveStore = trans.objectStore("Data");
        var saveRequest = saveStore.put(data);
        console.log('Data updated to Sent');
    }
    

    因为这都是在浏览器端的事务中完成的,所以它似乎工作得很好。一旦浏览器支持同步API,我就可以把它全部扔掉。

    旧线程,但使用事务将解决失败的解决方法。也就是说,事务只需要检查IndexedDB中的数据在发送后是否没有更改,如果没有更改,则将其标记为已发送。如果有更改,事务将在不写入的情况下结束。

    我认为不使用事务就无法访问IndexedDB。问题是,当我将数据发送到服务器时,事务不会保持打开状态。这称为乐观锁定: