2013-04-15 21 views
0

我的主要目標是在android/IOS的​​sqlite中將數據庫中的以下結構保存在數據庫中。 相應的表格將由編譯註意的外鍵組成。在phonegap中嵌套的sqlite事務

var tempData = [{ 
    name : "foo", 
    values : [{ 
      child : "foofoo", 
      value : [1, 2, 3] 
     }, { 
      child : "foofaa", 
      value : [5, 6, 7] 
     } 
    ] 
}, { 
    name : "bar", 
    values : [{ 
      child : "barbar", 
      values : [11, 22, 33] 
     }, { 
      child : "barbala", 
      values : [44, 55, 66] 
     } 
    ] 
}, { 
    name : "baz", 
    values : [{ 
      child : "bazbaz", 
      values : [444, 333, 222] 
     }, { 
      child : "bazbaazar", 
      values : [999, 888, 777] 
     } 
    ] 
}]; 

我寫了下面的代碼片斷來堅持上述結構。 這是用嵌套事務處理的傳統方法嗎? 或者我必須遵循一些標準?

下面的代碼工作正常,除了執行的順序不能保證。我在輸出中看到一些隨機行爲。我如何保證嵌套事務的同步行爲。我已經颳了很多網站,但無法找到一個坦率的解決方案。請幫忙

db.transaction(setupTable, dbErrorHandler, getEntries); 
function setupTable(tx) { 
doLog("before execute sql..."); 
tx.executeSql('CREATE TABLE IF NOT EXISTS mainTest(mainKey INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT NOT NULL)'); 
tx.executeSql('CREATE TABLE IF NOT EXISTS child(PKEY INTEGER PRIMARY KEY AUTOINCREMENT,parentKey INTEGER,children TEXT NOT NULL,FOREIGN KEY(parentKey) REFERENCES mainTest(mainKey))'); 
tx.executeSql('CREATE TABLE IF NOT EXISTS secondChild(SCKEY INTEGER PRIMARY KEY AUTOINCREMENT,spkey INTEGER,sales INTEGER,FOREIGN KEY(spkey) REFERENCES child(PKEY))'); 
doLog("after execute sql...");} 
function getEntries(tx) { 

//doLog("get entries"); 
/*dbShell.transaction(function(tx) { 
tx.executeSql("select id, title, body, updated from notes order by updated desc",[],renderEntries,dbErrorHandler); 
}, dbErrorHandler);*/ 

doLog("get entries"); 
db.transaction(function (tx) { 
    _.each(tempData, function (item) { 
     name = item.name; 
     tx.executeSql('INSERT INTO mainTest (name) VALUES("' + name + '")', [], function (tx, result) { 
      doLog("in child insert" + item.values); 
      doLog("in child insert" + JSON.stringify(tempData)); 
      _.each(item.values, function (item) { 
       doLog("in " + item.child); 
       tx.executeSql('INSERT INTO child (parentKey,children) VALUES((select mainKey from mainTest where name = "' + name + '"),"' + item.child + '")', [], function (tx, result) { 
        _.each(item.values, function (itemNew) { 
         tx.executeSql('INSERT INTO secondChild (spkey,sales) VALUES((select PKEY from child where children = "' + item.child + '"),"' + itemNew + '")', [], function (tx, result) {}, dbErrorHandler); 
        }); 
       }, dbErrorHandler); 
       doLog("after secondChild Insertion"); 
      }); 
      doLog("after child insertion"); 
     }, dbErrorHandler); 
     doLog("after main insertion"); 
    }); 
}, dbErrorHandler);} 
+0

代碼中沒有嵌套事務。 –

+0

那麼你認爲這是什麼?我應該採取什麼方法來堅持上述結構? –

回答

1

我想我理解你的觀點。

讓我試着幫助:

我用類似的代碼工作,以儘量保證交易的特定的順序,但在我個人的意見(由於最近的經驗),你必須尋找一個解決方案嵌套交易... 我的問題是我必須把我的phonegap應用程序到WinPhone 8的時間,其中數據庫的功能不是本地可用於cordova和第一個解決方案是包括/開發一個插件。我找到的那個不能處理嵌套事務,你可以想象重寫/重新設計程序有多難:/關於javascript的異步模型的思考我找到了一個答案:我創建了自定義事件來確定是否一個事務完成並在該事件的偵聽器內運行下一個事務。

//event var 
var EVENT_TRANSACTION_ENDED_ = document.createEvent('Event'); 
//init the event 
EVENT_TRANSACTION_ENDED_.initEvent('EVENT_TRANSACTION_ENDED_', true, true); 
//listener to the event 
document.addEventListener('EVENT_TRANSACTION_ENDED_', onEventFunctionHandler, false); 

//first transaction 
db.transaction(function(tx){ 
    //sample query 
    tx.executeSql('SELECT * FROM TABLE', [], function(tx){ 
     //notify first transaction ended 
     console.log('First transaction'); 
     setTimeout('document.dispatchEvent(EVENT_TRANSACTION_ENDED_);', 100); 
    }, dbErrorHandler); 
}, dbErrorHandler); 

// 
function onEventFunctionHandler(e){ 
    //second transaction 
    db.transaction(function(tx){ 
     //sample query 
     tx.executeSql('SELECT * FROM ANOTHER_TABLE', [], function(tx){ 
      //notify SECOND transaction ended 
      console.log('SECOND transaction'); 
     }, dbErrorHandler); 
    }, dbErrorHandler); 
} 

這對我有效,希望這有助於。

0

您必須對tx.executeSql使用成功回調函數。優點還在於,如果您的第一個SQL語句中有錯誤,那麼第二個SQL語句將不會被執行。所以你不會在你的數據庫中出現不一致。 幫我:

 db.transaction(function(tx){ 
      tx.executeSql('DELETE FROM object WHERE object_id IN(1,2)'); 
      }, errorCB, function(){ 
      db.transaction(function(tx){ 
       tx.executeSql('INSERT INTO object '+values_object); 
       }, errorCB, successCB 
      ); 
      } 
     ); 

線索是執行第二交易的第一筆交易的成功回調。所以這些語句按照定義的順序執行。