概述: 我正在尝试避免从网页和 Web Worker 访问 IndexedDB 时的竞争条件。
设置: 一个网页正在将项目保存到本地的 IndexedDB 中,用户在使用该站点时可以保存数据。每当用户将数据保存到本地数据库中时,记录都会被标记为“未发送”。
另外还有一个 Web Worker 后台线程,它从 IndexedDB 中获取数据并将其发送到服务器。一旦服务器接收到数据,就会将其标记为“已发送”。
问题: 由于访问 IndexedDB 是异步的,我无法保证用户不会在 Web Worker 发送数据到服务器的同时更新记录。时间轴如下所示:
- Web Worker 从数据库获取数据并将其发送到服务器
- 传输正在进行时,用户更新数据并将其保存到数据库中
- Web Worker 接收到来自服务器的响应,然后将数据库更新为“已发送”
- 现在数据库中有尚未发送到服务器但被标记为“已发送”的数据
失败的解决方案: 在从服务器接收到响应后,我可以重新检查行以查看是否发生了更改。然而,我仍然面临着一个小窗口的问题,在这个窗口内数据可以被写入数据库并且永远不会被发送到服务器。
例如: 在服务器表示数据已保存后,然后:
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-database)。 我认为同步API是为Web Workers设计的,以避免出现这种情况。
如有任何想法,请不吝赐教。我已经在处理这个问题上工作了一个星期,但一直没有找到可行的解决方案。