[whatwg] Comments on updated SQL API
Ian Hickson
ian at hixie.ch
Mon Sep 24 21:18:04 PDT 2007
On Sat, 22 Sep 2007, Timothy Hatcher wrote:
>
> The callback syntax is nice but the implicit thread-global transaction
> is confusing and can lead to programmer error and unneeded database
> locking.
There isn't really a thread-global transaction, the transactions are
per-sequence-of-executeSql-calls, as in:
executeSql('sql1', function (result) {
executeSql('sql2', function (result) {
executeSql('sql3', function (result) {
// this is all in one transaction
});
});
});
executeSql('sql4', function (result) {
executeSql('sql5', function (result) {
executeSql('sql6', function (result) {
// this is all in another transaction
});
});
});
...where the likely order of execution is sql1 and sql4 at the same time,
then sql2 and sql5, then sql3 and sql6, assuming all the statements take
the same amount of time.
> It doesn't look like you can rollback the implicit transaction (one of the big
> features of transactions.)
You can rollback just by throwing an exception in the callback.
> Also what access locks does the implicit transaction take? What if you
> need exclusive access to the database temporarily? These cases would be
> solved by adding explicit transactions with control to access locks and
> rolling back.
There are various ways of solving these, indeed. Another way would be to
support 'BEGIN TRANSACTION EXCLUSIVE' as the first statement of a
transaction, which would set the transaction type. (e.g.)
> Here is an example:
>
> transation1 = db.beginTransation();
> transation1.executeQuery("SELECT * FROM document", function(result1) {
> if(...) {
> result1.transation.executeQuery("UPDATE document WITH ... WHERE
> document = ?", result1.namedItem("id"), function(result2) {
> ...
> });
> }
> });
>
> transation2 = db.beginTransation(Database.ExclusiveTransactionLocks);
> transation2.executeQuery("UPDATE user WITH ... WHERE user = ?", "123",
> function(result1) {
> if(...) {
> result1.transation.executeQuery("UPDATE user WITH ... WHERE user =
> ?", result1.namedItem("id"), function(result2) {
> result1.transation.commit();
> });
> } else {
> result1.transation.rollback();
> }
> });
This is basically what the spec supports now, except without any explicit
mentioning of the transactions.
> I think an explicit commit should be required for the transactions. So
> you can keep the transcript object around and add to it over time.
Currently the spec commits if you don't add a new query to the
transaction. Could you elaborate on your use case?
> Some other comments:
>
> You might notice that I have been using executeQuery() instead of
> executeSql(). I think it is weird and unneeded to say Sql in the
> function name. If anything, it should be executeSQL().
The name "sql" is there so that we can add other types of queries at a
later date. The capitalisation is based on typical capitalisation of other
members in the DOM.
> I think the ResultSet object should have a property to get the Database
> and the Transaction objects. As I mentioned earlier, not everyone will
> use closures and will need access to these to do anything else.
You don't need access to the transaction object if anything executed
during the callback is added to the transaction, as far as I can tell; and
the database would just be the database... you can pass that around
however you like, no need for an explicit member.
--
Ian Hickson U+1047E )\._.,--....,'``. fL
http://ln.hixie.ch/ U+263A /, _.. \ _\ ;`._ ,.
Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
More information about the whatwg
mailing list