- html - 我的下拉菜单的内容关闭得太快
- c# - 使用 Html Agility Pack 从网页中的表中获取值而不使用 "SelectNode'
- html - 内容容器下的 CSS 下拉菜单
- html - 如何停止嵌套列表重叠父列表?
据我了解,将多个 IndexedDB 操作放在单个事务中而不是为每个操作使用唯一的事务有三个不同的原因:
#1 没问题,大多数数据库都有相同的特征。
#2 有点独特,与#3 一起考虑时会引起问题。假设我有一些简单的函数,可以将一些内容写入数据库并在结束时运行回调:
function putWhatever(obj, cb) {
var tx = db.transaction("whatever", "readwrite");
tx.objectStore("whatever").put(obj);
tx.oncomplete = function () { cb(); };
}
效果很好。但现在,如果您想将该函数作为一组操作的一部分来调用,并且希望以原子方式提交或失败,这是不可能的。你必须做这样的事情:
function putWhatever(tx, obj, cb) {
tx.objectStore("whatever").put(obj).onsuccess = function () { cb(); };
}
该函数的第二个版本与第一个版本非常不同,因为回调在保证将数据写入数据库之前运行。如果您尝试读回刚刚写入的对象,您可能会得到一个过时的值。
基本上,问题在于您只能利用#2 或#3 之一。有时选择是明确的,但有时则不然。这导致我编写了可怕的代码,例如:
function putWhatever(tx, obj, cb) {
if (tx === undefined) {
tx = db.transaction("whatever", "readwrite");
tx.objectStore("whatever").put(obj);
tx.oncomplete = function () { cb(); };
} else {
tx.objectStore("whatever").put(obj).onsuccess = function () { cb(); };
}
}
但是,即使这仍然不是通用解决方案,在某些情况下可能会失败。
还有其他人遇到过这个问题吗?你如何解决?或者我只是以某种方式误解了事情?
最佳答案
以下只是意见,因为这似乎不是一个“唯一正确答案”的问题。
首先,性能是一个无关紧要的考虑因素。完全避免这个因素,除非后来的分析表明存在重大问题。出现性能问题的可能性非常低。
其次,我更喜欢将请求组织到事务中,只是为了保持完整性。诚信至关重要。我在这里定义的完整性仅仅意味着数据库在任何一个时间点都不包含冲突或不稳定的数据。本质上,数据库永远无法进入“坏”状态。例如,施加一个规则,即跨存储对象引用指向其他存储中有效且现有的对象(也称为引用完整性),或者防止重复请求,例如双重添加/放置/删除。显然,如果该应用程序类似于贷记/借记帐户的银行应用程序或心脏病发作监控应用程序,那么事情可能会出现严重错误。
我自己的经验让我相信涉及indexedDB的代码不容易出现传统的外观模式。我发现,就将请求组织到不同的包装函数中而言,最有效的方法是围绕事务设计函数。我发现很多时候很少DRY violations因为每个请求对于其事务上下文来说几乎总是唯一的。换句话说,虽然类似的“放置对象”请求可能出现在多个事务中,但鉴于其单独的上下文,其行为是如此不同,以至于值得违反 DRY。
如果您使用每个请求路由的函数,我不确定您为什么要检查事务参数是否未定义。让调用者创建该函数,然后依次将其传递给请求。期望交易始终被定义,并且不要过度热心地防范它。如果它没有被定义,那么在indexedDB或你的调用函数中可能存在严重的错误。
明确地说,类似于:
function doTransaction1(db, onComplete) {
var tx = db.transaction(...);
tx.onComplete = onComplete;
doRequest1(tx);
doRequest2(tx);
doRequest3(tx);
}
function doRequest1(tx) {
var store = tx.objectStore(...);
// ...
}
// ...
如果请求不应并行执行,而必须串行运行,那么这表明存在更大且更困难的设计问题。
关于javascript - IndexedDB 事务的目的相互冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27791057/
是否可以从浏览器外部或创建它的域外部访问 IndexedDB? 我正在考虑将数据存储到与某个特定域相关的某些 IndexedDB 的情况,因为它总是这种情况,然后在第一个域不复存在后访问该数据,或将其
我有一个员工在断开连接模式下使用的渐进式网络应用程序。他们扫描商店中的库存商品,该应用程序搜索本地数据以查找扫描的商品(indexedDb 数据存储,约有 1/2 百万条记录)。 此数据通过 API
有人可以告诉我是否可以使用 index、openCursor 和 keyRange 在 indexeddb 对象存储上执行不区分大小写的搜索.... 我可以区分大小写并设法使用 toUpperCase
来自提供的示例here和 here 它们展示了创建请求,然后在发出请求后附加 onerror 和 onsuccess 处理程序。 var transaction = db.transaction(["
假设您正在构建一个框架 Foobar,并假设 Foobar 有一个函数 .coolstuff(),它会调用 IndexedDB 调用 .coolstuff2() 和 .coolstuff3(),当这两
只要您使用适当的 IDBTransaction,是否可以从单个事务中完成所有这些操作,而不是打开多个事务(读取表、写入表、写入另一个表等)? Mozilla 说:“保持事务处于事件状态的唯一方法是对其
我有一个小项目,将数据存储在浏览器的 IndexedDB 中。我想添加同步功能,以便用户可以在任何地方访问数据。 如何在远程服务器或服务器数据库中同步本地 IndexedDB 数据,以便我可以在任何地
我想在 onupgradeneeded 中更新我的 indexeddb 数据库的对象库之一。我想检查一下,如果这个索引存在于这个对象存储中,那么就不需要做任何更改。但如果不是,我想更新它的索引。 最佳
有没有办法检查 IndexedDB 数据库是否已经存在?当程序试图打开一个不存在的数据库时,该数据库被创建。 我能想到的唯一方法是如下所示,我测试 objectStore 是否已经存在,如果不存在,则
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我的代码如下: ... var f1 = function(trans) { var store = trans.objectStore('ObjectStore'); store.clear
我在我的一页中创建了一个 IndexdDB 对象存储(让对象存储名称为“ShopStore”)。现在我想从不同的页面打开相同的对象存储。可能吗? 我的两个网页位于不同的域。 最佳答案 根据MDN您无法
我有一个 Epub 注释插件,用户可以在其中对 Epub 进行注释,但是注释文本存储在浏览器中的 indexeddb 数据库中,想将这些注释文本导出到文件中,而在其他系统中,我想将这些文件导入到我的
在之前的 IndexedDB 规范 ( http://www.w3.org/TR/2011/WD-IndexedDB-20111206 ) 中,IDBDatabase 事务的模式值很短。在当前规范(2
有没有办法对 IndexedDB 中的同一属性进行 OR 或 IN 查询? 换句话说,我如何得到结果, SELECT * FROM MyTable WHERE columnA IN ('ABC','D
据我了解,IndexedDB 是大多数跨浏览器在线数据库解决方案的方式。甚至可能在 FF 等浏览器中使用这个 polyfill。 我试图找到一个非常简单的页面,它使用 IndexedDB 最初填充数据
给定一个带有一个声明对象存储的 indexeddb 数据库: var objectStore = thisDb.createObjectStore("table", {keyPath: "id", a
我正在构建一个利用 IndexedBD 的网络应用程序。我来自 SQL 背景,所以概念不同。具体来说,我的理解是 indexedDB 中没有“外键”的真正概念。因此,我试图找出检索相关对象的最快方法,
我在不做任何其他修改的情况下升级版本时遇到此代码问题,我无法理解原因。 function create_registry() { var version = 1; var indexe
我使用下面的代码从 indexeddb 中选择所有列 this._connection.openDb(this._indexedDBLiveDBName); return this._
我是一名优秀的程序员,十分优秀!