嗨,我正在尝试更新记录indexdb。我想实现一个泛型方法,允许我升级到任何领域。
为此,我有一个函数返回我需要的记录。
function getObjectStoreClienteDB(clave,valor){
//Ahora recogeremos los datos de nuestro almacén "Productos"
var transaction = db.transaction(["customers"], "readwrite");
var objectStore = transaction.objectStore("customers");
var index = objectStore.index(clave);
var singleKeyRange = IDBKeyRange.only(valor);
// To use one of the key ranges, pass it in as the first argument of openCursor()/openKeyCursor()
return index.openCursor(singleKeyRange);
} ,另一个更新返回的记录。
function updateClienteDB(clave,valor,newvalor){
console.log("updateClienteDB ... clave: "+clave+" valor: "+valor+" newvalor: "+newvalor);
var objectStore = db.transaction(["customers"], "readwrite").objectStore("customers");
request = getObjectStoreClienteDB("name",valor);
request.onsuccess = function(event) {
// Get the old value that we want to update
var data = request.result;
// update the value(s) in the object that you want to change
if(clave=="name")
data.name = newvalor;
else if(clave=="email")
data.email = newvalor;
else if(clave=="matricula")
data.matricula = newvalor;
else if(clave=="telefono")
data.telefono = newvalor;
// Put this updated object back into the database.
var requestUpdate = objectStore.put(data);
requestUpdate.onerror = function(event) {
console.log("addCliente ..."+name+" "+email +" "+ event.target.errorCode);
};
requestUpdate.onsuccess = function(event) {
console.log("All done!");
};
};
}在行中: var requestUpdate =objectStore.put(数据);
错误:未捕获TransactionInactiveError:无法对‘IDBObjectStore’执行'put‘:事务已完成。
发布于 2014-12-31 06:24:37
尝试使用相同的readwrite事务。看起来您正在调用db.transaction(...)在两个地方。然后,您尝试在不同事务的上下文中更新链接到不同事务的对象存储区。结果是其中一个事务完成(其生命周期结束),可能是因为它超时了,因为它没有检测到任何注册的请求。objectStore变量位于提早完成的事务的生存期内,因此您会得到一个事务已完成错误。
这个问题很容易解决。您只需在同一事务的生命周期结束之前在其上注册一个新请求( put请求)。为此,您可以(a)内联语句request = getObjectStoreClienteDB("name",valor);,以便将其附加到同一事务实例,或者(b)将事务实例存储在单独的变量中,并在两个调用中引用该变量。
例如,以下代码是使用单个事务的修改代码:
// this function was changed, it now takes an active transaction as its first argument.
function getObjectStoreClienteDB(transaction, clave,valor){
//Ahora recogeremos los datos de nuestro almacén "Productos"
// this was changed. instead of creating a new transaction we just reference the
// transaction instance passed to this function
var objectStore = transaction.objectStore("customers");
var index = objectStore.index(clave);
var singleKeyRange = IDBKeyRange.only(valor);
// To use one of the key ranges, pass it in as the first argument of openCursor()/openKeyCursor()
return index.openCursor(singleKeyRange);
}
function updateClienteDB(clave,valor,newvalor){
console.log("updateClienteDB ... clave: "+clave+" valor: "+valor+" newvalor: "+newvalor);
// this line was added. we create the transaction here, once
var transaction = db.transaction(["customers"], "readwrite");
// this line was changed, we simply reference the transaction instance here instead of
// creating a second transaction
var objectStore = transaction.objectStore("customers");
// this line was changed, we pass in the one active transaction instance to the function
// now instead of having the function create its own transaction
request = getObjectStoreClienteDB(transaction, "name",valor);
request.onsuccess = function(event) {
// Get the old value that we want to update
var data = request.result;
// update the value(s) in the object that you want to change
if(clave=="name")
data.name = newvalor;
else if(clave=="email")
data.email = newvalor;
else if(clave=="matricula")
data.matricula = newvalor;
else if(clave=="telefono")
data.telefono = newvalor;
// Put this updated object back into the database.
// this line now works. objectStore is attached to our 1 transaction that is still 'alive'
// because it gets registered 'in time' (before transaction finishes due to timeout due
// to no additional requests registered in allowed time window).
var requestUpdate = objectStore.put(data);
requestUpdate.onerror = function(event) {
console.log("addCliente ..."+name+" "+email +" "+ event.target.errorCode);
};
requestUpdate.onsuccess = function(event) {
console.log("All done!");
};
};
}为了清楚起见,这里有第二个例子。它使用调用者的事务重新创建对对象存储的引用,而不是交叉引用附加到不同事务的对象存储:
function updateClienteDB(clave,valor,newvalor){
console.log("updateClienteDB ... clave: "+clave+" valor: "+valor+" newvalor: "+newvalor);
var objectStore = db.transaction(["customers"], "readwrite").objectStore("customers");
request = getObjectStoreClienteDB("name",valor);
request.onsuccess = function(event) {
// Get the old value that we want to update
var data = request.result;
// update the value(s) in the object that you want to change
if(clave=="name")
data.name = newvalor;
else if(clave=="email")
data.email = newvalor;
else if(clave=="matricula")
data.matricula = newvalor;
else if(clave=="telefono")
data.telefono = newvalor;
// Put this updated object back into the database.
// the following line is changed so that it works.
//var requestUpdate = objectStore.put(data);
var theOtherTransactionThatIsStillAlive = event.transaction;
var objectStoreFromValidTransaction = theOtherTransactionThatIsStillAlive.objectStore('customers');
var requestUpdate = objectStoreFromValidTransaction.put(data);
requestUpdate.onerror = function(event) {
console.log("addCliente ..."+name+" "+email +" "+ event.target.errorCode);
};
requestUpdate.onsuccess = function(event) {
console.log("All done!");
};
};
}https://stackoverflow.com/questions/27709648
复制相似问题