2016-06-22 76 views
0

我正在开发一个应用程序,它广泛使用IndexedDB。我想要做的是保存员工的数据表和公司表的数据。

每个员工都属于一个公司,而员工对象我有Company's ID,这两个实体的对象都是这样的。在回调中抛出IDBTransaction抛出TransactionInactiveError

公司的目标:

{"id":1,"name":"ABC"} 

员工对象:

{"id":100,"name":"E1","company_id":1} 

我节省使用自动递增的关键公司的详细信息(称之为appid),所以我的最终目标公司的外观如下:

{"id":1,"name":"ABC","appid":1} 

当我插入公司的记录时,appid会自动递增。
现在同时将员工的目标,我想找到该公司的本地ID(appid)并将其保存在员工的目标,使员工的物体看起来像:

{"id":100,"name":"E1","company_id":1,"company_app_id":1} 

我能够得到的本地ID公司通过调用一个方法,同时节省了员工的详细信息,如:

var transaction = db.transaction(['employees'], 'readwrite'); 
var objStore = transaction.objectStore('employees'); 
var company_id=employeeobject.company_id; 
companyDB.getCompanyById(company_id,function(companyObject){ 
     transaction = db.transaction(['employees'], 'readwrite'); 
     objStore = transaction.objectStore('employees'); 
     // If I comment above two lines it throws me exception. 
     var request=objStore.put(employeeobject); 
     request.onsuccess = function (e) { 
      // using it for next insertion. 
     }; 
}); 

问题与上面的代码是每次当我想插入员工在表中的数据,我需要重新在回调函数中trascation,因为如果我不不开放交易再次抛出TransactionInactiveError

我在SO上搜索了特定的错误,发现事务一旦在当前范围内不再使用就立即失效。

当我有几个员工的对象时,上面的代码工作得很好。 但是当我试图用〜1K的数据执行相同的代码时,它需要 (正常执行时间x〜10)。

正常执行时间我的意思是没有获取公司的localid并直接保存员工的详细信息。


所以我的问题是,什么是我可以插入员工的数据,包括公司的本地ID与至少执行时间的最佳方式?或者我做错了什么?

回答

0

嗯,也许这样的事情有帮助吗?

function addCompany(db, company, callback) { 
    var tx = db.transaction('companies', 'readwrite'); 
    var store = tx.objectStore('companies'); 
    var request = store.add(company); 
    request.onsuccess = callback; 
} 

function addEmployee(db, employee, callback) { 
    var tx = db.transaction('employees', 'readwrite'); 
    var store = tx.objectStore('employees'); 
    var request = store.add(employee); 
    request.onsuccess = callback; 
} 


function addCompanyThenEmployee(db, company, employee, callback) { 
    addCompany(db, company, onAddCompany); 

    function onAddCompany(event) { 
    var newAppId = event.target.result; 
    employee.company_app_id = newAppId; 
    addEmployee(db, employee, callback); 
    } 
} 


var company = {'id': 1, 'name': 'xyz'}; 
var employee = {'id': 1, 'name': 'xyz'}; 

var request = indexedDB.open(...); 
request.onsuccess = function(event) { 
    var db = event.target.result; 
    addCompanyThenEmployee(db, company, employee, onAddCompanyThenEmployee.bind(null, company, employee)); 
}; 

function onAddCompanyThenEmployee(company, employee, event) { 
    console.log('Added company', company, 'and employee', employee); 
}; 
+0

这将解决单一企业与单一的雇员。正如我在我的问题中提到的那样,我写的代码对于单个条目可以很好地工作。我有更多的1K的公司和10K的员工。所以在这种情况下,我无法弄清楚这将如何工作! –

1

这取决于你如何实施companyDB.getCompanyById()。如您所见,索引DB数据库事务仅在创建后立即生效(1),并且(2)在来自请求的回调中该事务,直到“控制返回到事件循环”。没有进一步的细节,最好的办法就是批量处理 - 为N名员工执行getCompanyById()查找,然后编写这N个记录。

但是从顶部的描述“......员工表和公司表中的数据......”也许这是所有在一个单一的索引DB数据库,在这种情况下,只使用一个单一的交易的一切:

var tx = db.transaction(['companies', 'employees'], 'readwrite'); 
employee_records.forEach(function(record) { 
    var company_id = record.company_id; 
    var req = tx.objectStore('companies').get(company_id); 
    req.onsuccess = function() { 
    var company = req.result; 
    record.company_app_id = company.app_id; 
    tx.objectStore('employees').put(record); 
    }; 
}); 

(我在这里破坏您的实际数据/逻辑,这只是为了说明)

+0

不,它与indexeddB数据库不同。我首先插入数据库中的所有公司,然后希望将公司的localid插入员工的详细信息。在上述代码/逻辑中根本没有网络呼叫。 –