Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is possible to abort all pending transactions before deleting DB? #367

Open
sriram275 opened this issue Oct 19, 2015 · 7 comments
Open

Is possible to abort all pending transactions before deleting DB? #367

sriram275 opened this issue Oct 19, 2015 · 7 comments

Comments

@sriram275
Copy link

Hi..,
I am doing more than 2000 records inserting or updating..so it will run in background. If I want to delete the db by clicking on stop and delete from user while transactions are in background. Is possible to abort all pending transactions and then delete the DB.
I have seen some piece of code from SQLiteplugin.js

deleteDb: function(first, success, error) {
      var args, dblocation;
      args = {};
      if (first.constructor === String) {
        args.path = first;
        args.dblocation = dblocations[0];
      } else {
        if (!(first && first['name'])) {
          throw new Error("Please specify db name");
        }
        args.path = first.name;
        dblocation = !!first.location ? dblocations[first.location] : null;
        args.dblocation = dblocation || dblocations[0];
      }
      delete SQLitePlugin.prototype.openDBs[args.path];
      return cordova.exec(success, error, "SQLitePlugin", "delete", [args]);
    }
  };

In this method before we calling delete SQLitePlugin.prototype.openDBs[args.path]; can we abort all pending transactions.?

And more over we have already abort pending transactions method also.

SQLitePlugin.prototype.abortAllPendingTransactions = function() {
    var tx, txLock, _i, _len, _ref;
    txLock = txLocks[this.dbname];
    if (!!txLock && txLock.queue.length > 0) {
      _ref = txLock.queue;
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        tx = _ref[_i];
        tx.abortFromQ(newSQLError('Invalid database handle'));
      }
      txLock.queue = [];
      txLock.inProgress = false;
    }
  };

So I am using this method to abort all pending transactions of the DB( by passing DB name instead of this.dbname) which I am trying to Delete.

It is working fine but some cases its throwing some exception and stuck the application.

Let me know your thoughts and if you have any other option to abort pending transactions before deleting that DB.

@brodycj
Copy link
Contributor

brodycj commented Oct 19, 2015

Yes but it would be a bit of a challenge to get this right. Basically, we would remove all transactions from the queue except for the transaction that is currently in progress, keep a record that the user is attempting to delete the database, and wait for the transaction to finish.

I have already raised #210 to abort all pending transactions when closing a database.

@sriram275
Copy link
Author

In DB close also we are checking about in progress transactions..so if any pending transactions are there then it's throwing exception..

SQLitePlugin.prototype.close = function(success, error) {
    if (this.dbname in this.openDBs) {
      if (txLocks[this.dbname] && txLocks[this.dbname].inProgress) {
        console.log('cannot close: transaction is in progress');
        error(newSQLError('database cannot be closed while a transaction is in progress'));
        return;
      }
      console.log('CLOSE database: ' + this.dbname);
      delete this.openDBs[this.dbname];
      if (txLocks[this.dbname]) {
        console.log('closing db with transaction queue length: ' + txLocks[this.dbname].queue.length);
      } else {
        console.log('closing db with no transaction lock state');
      }
      cordova.exec(success, error, "SQLitePlugin", "close", [
        {
          path: this.dbname
        }
      ]);
    } else {
      console.log('cannot close: database is not open');
      if (error) {
        nextTick(function() {
          return error();
        });
      }
    }
  };

So if any pending transactions are there then it won't close the DB.

Let me know if the following steps will helpful means..

abortAllPendingTransactions ( for abort pending transactions )
close ( to close DB )
deleteDb ( to delete the DB )

@brodycj
Copy link
Contributor

brodycj commented Oct 19, 2015

In general that sounds like a good approach. The one issue is that if there is a transaction already in progress, it will probably finish up can call its success callback if successful.

@sriram275
Copy link
Author

Hi..,
The above approach is working fine but in some cases it's failing..

one of the situation is:

var tempDb = 'tempInv24537.db';
 if (tempDb != '') {
            window.sqlitePlugin.abortPendingtempTransaction(tempDb); //created new method from your existing method and passing db name
            setTimeout(function () { $cordovaSQLite.deleteDB(tempDb); }, 100);
        }

in the above example I am trying to abort all pending transactions and then deleting db...but if the pending transactions are more and it is in process of trying to abort all pending ones meanwhile deleteDB is called and db is deleted. In this case app is getting hanged and user not able to do any function on the app. (I am running app through xcode so once its gets hanged then in xcode it is going to a pointer to the line in SQLitePlugin.m at 373 i.e previousRowsAffected )

So my question:
is possible to have abortpendingtransaction method with promise..? so once after aborting all transactions then only we will call deleteDB method and then it will care of delete DB.

Why I am asking all these because we are dealing with temparary dbs which are for just in case..which will work on one a particular page and user is leaving from that page I want to delete that DB..I don't want store all DBs. So while user is in that page there should be one temporary DB.

If you have any other approach other than this let me know..

@brodycj
Copy link
Contributor

brodycj commented Oct 27, 2015

Would an in-memory database solve your issue?

@sriram275
Copy link
Author

I don't know much about in-memory database..but by checking this In-Memory Databases I came to know that

  • Create it with the filename ":memory:":
  • It'll cease to exist as soon as the connection to it is closed.

will this plugin( either cordova sqlite storage or cordova sqlite evfree) support with in-memory database?
can we do the same transactions(insert,update and delete) like what we are doing with .db?

@brodycj
Copy link
Contributor

brodycj commented Oct 27, 2015

Unfortunately I do not expect the in-memory databases to work correctly with this plugin since each implementation will try prepending the implementation-specific database storage path before the sqlite3_open() call. I cannot promise when I will be able to fix this due to my existing backlog of both paid and free software work.

The recommended workaround is to keep a limited set of temporary database tables that you can clear by using DROP or DELETE FROM when a new page is loaded.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants