Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTML 5 Web SQL Database Transaction commit or rollback when refreshing page

As written in the Safari Client-Side Storage and Offline Applications Programming Guide, rolling back a HTML 5 Web SQL Database transaction is done by returning true in the callback function provided as an error callback to a transaction the executeSql method:

The per-query error-handling callback is rather straightforward. If the callback returns true, the entire transaction is rolled back. If the callback returns false, the transaction continues as if nothing had gone wrong. Thus, if you are executing a query that is optional—if a failure of that particular query should not cause the transaction to fail—you should pass in a callback that returns false. If a failure of the query should cause the entire transaction to fail, you should pass in a callback that returns true.

For example if I have the following transaction (suppose the 'users' table has a UNIQUE constraint on the 'username' field and username 'test' already exists - which I'm trying to insert again, which should result in a constraint error):

database.transaction(function(transaction) {
    transaction.executeSql(
        "INSERT INTO users (username) VALUES('test')",
        null,
        dataCallback,
        errorCallback
     );
});

function errorCallback() {
    return true; //this causes the rollback
}

I have two questions:

  1. If I have to include many operations inside a transaction (for example I have to send some data using ajax to a server and wait for the response, etc.) and the user reloads the page before the response had arrived (which means that the errorCallback won't be called), will the transaction be commited or will it fail ?

  2. Does anyone know how to rollback a Web SQL transaction manually ? For example if I want to rollback a transaction based on the result of an ajax call, how can it be done ? Should I run a query which contains an error to make sure that the error callback is called ?

Thanks.

like image 1000
SzilardD Avatar asked Feb 28 '11 14:02

SzilardD


People also ask

What is the difference between rollback and commit in SQL?

The COMMIT statement lets a user save any changes or alterations on the current transaction. These changes then remain permanent. The ROLLBACK statement lets a user undo all the alterations and changes that occurred on the current transaction after the last COMMIT.

Do we need to commit after rollback?

I have confirmed that after rollback we cannot commit the same transaction. Make sure another transaction is not in waiting, else it will be committed. Also don't do anything with transaction in finally block. Always use finally block to close connection , data reader etc.

Is transaction should end with either commit or rollback?

A transaction ends when it is committed or rolled back, either explicitly (with a COMMIT or ROLLBACK statement) or implicitly (when a DDL statement is issued). To illustrate the concept of a transaction, consider a banking database.

Which method is used to rollback the transaction?

The rollback SQL statement is used to manually rollback transactions in MS SQL Server.


2 Answers

  1. The transaction will be committed.
  2. Yes, to rollback explicitly, you must invoke invalid query explicitly. This is recommended workaround since the quick-and-dirty API is missing abort method.

Regarding AJAX, be ready all data, before you start a write transaction. You won't have any problem as you described. Use database constraint (UNIQUE, FOREIGNKEY) as much possible.

like image 155
Kyaw Tun Avatar answered Oct 10 '22 02:10

Kyaw Tun


Have you found a way to do AJAX calls during the transaction? I haven't finished reading the whole spec, but so far it looks like once your SQLTransactionCallback or SQLTransactionSyncCallback returns, you can’t add any more stuff to the transaction — or can you? Maybe from the results callback?

Edit: Now that I look again, the spec (which contains many fewer errors than the Apple document you linked to, but is not as easy to read) says this:

  1. If the method [executeSql] was not invoked during the execution of a SQLTransactionCallback, SQLStatementCallback, or SQLStatementErrorCallback then raise an INVALID_STATE_ERR exception.

So I think that means there's no way to do it.

Further edit: No, wait! As long as the SQLStatementCallback takes some time to get called, you could busy-wait doing select 3 + 4 over and over again, each time from the statement callback of the previous select 3 + 4, until your AJAX call sets a flag somewhere that has the data you want. This is terrible programming (it'll eat lots of CPU for no good reason, might block lower-priority tasks like redisplaying the page) but I think it's probably the only way to keep a transaction open for an arbitrary period of time. Too bad you can't select 3 + 4, sleep(1) in SQLite.

In general SQLite (the underlying storage engine here) rolls back uncompleted transactions. I haven’t yet tested the page-reload error case you're asking about. I would be very surprised if it was committed.

By the way, thank you very much for posting this question. I had been trying to figure out how to get the transaction to rollback, even though it is meticulously documented in the original spec.

like image 34
Kragen Javier Sitaker Avatar answered Oct 10 '22 01:10

Kragen Javier Sitaker