简体   繁体   English

在phonegap中嵌套的sqlite事务

[英]nested sqlite transaction in phonegap

My primary aim is to persist the following structure in a db in sqlite for android/IOS. 我的主要目的是在sqlite中为db / android保存以下结构。 The corresponding table will consist of foreign keys which is being taken care by the pragma. 相应的表将包含由pragma正在处理的外键。

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]
        }
    ]
}];

I have written the below snippet for persisting the above structure. 为了坚持上述结构,我写了下面的代码片段。 Is this the conventional method for getting over with nested transactions ? 这是用于克服嵌套事务的传统方法吗? Or i have to follow some standards ? 或者我必须遵循一些标准?

The below code is working fine, except that the order of execution is not guaranteed. 以下代码工作正常,但不保证执行顺序。 I am seeing some random behaviour in the output. 我在输出中看到一些随机行为。 How can i guarantee synchronous behavior for nested transactions. 如何保证嵌套事务的同步行为。 I have scraped many sites but could not find a candid solution for this. 我已经抓了很多网站,但找不到坦诚的解决方案。 Please help 请帮忙

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);}

I think I understand your point. 我想我理解你的观点。

Let me try to help: 让我试着帮忙:

I was working with similar code, in order to try to guarantee specific order of transactions, but in my personal opinion (due to a recent experience) you have to look for a workaround to nested transactions... My issue was related to the time I had to take my phonegap app to WinPhone 8 where capabilities of database are not native available for cordova and the first solution was to include/develop a plugin. 我正在使用类似的代码,以便尝试保证特定的交易顺序,但在我个人看来(由于最近的经验)你必须寻找嵌套交易的解决方法......我的问题与时间有关我不得不将我的phonegap应用程序带到WinPhone 8,其中数据库的功能不是本机可用于cordova,第一个解决方案是包含/开发插件。 The one that I found was not able to deal with nested transactions and you can imagine how hard was to rewrite/redesign the program :/ Thinking of the async model of javascript I found one answer: I've created custom events to determine whether a transaction is finished and inside the listener of that event, run the next transaction. 我找到的那个是无法处理嵌套事务的,你可以想象重写/重新设计程序是多么困难:/思考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);
}

That worked for me, hope this helps. 这对我有用,希望这会有所帮助。

You have to use success callback function with tx.executeSql. 您必须使用tx.executeSql成功回调函数。 The advantage also is, that if there is an error in your first SQL Statement the second will not be executed. 优点还在于,如果第一个SQL语句中存在错误,则第二个SQL语句将不会执行。 So you do not get inconsistency in your database. 因此,您不会在数据库中出现不一致。 This helped me: 这对我有所帮助:

        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
            );
            }
        );

The clue is to execute the second transaction as success callback of the first transaction. 线索是执行第二个事务作为第一个事务的成功回调。 So the statements are executed in defined order. 因此语句按定义的顺序执行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM