Gerry, David, you are both right.

The possibility of a bug is thus eliminated for good. And 
https://www.sqlite.org/isolation.html <https://www.sqlite.org/isolation.html> 
is, strictly speaking, accurate, even if it another document is needed to avoid 
any interpretation doubt (http://www.sqlite.org/lang_transaction.html 
<http://www.sqlite.org/lang_transaction.html>).

Fact is, I spent a few days clearing things up, until I could eventually reach 
a correct program despite fuzzy premises ;-) Documentation is hard, and one 
never stops learning SQLite. Thanks for your quick and precise answers!

Gwendal


> Le 18 juil. 2017 à 15:43, David Raymond <david.raym...@tomtom.com> a écrit :
> 
> I think the documentation's good. I think you're missing the whole point of a 
> deferred transaction: that it doesn't start a "transaction" until it needs 
> to. You can run "begin deferred transaction" then walk away for 3 months 
> without upsetting anything. If you need the precise timing then why not just 
> use "begin immediate"?
> 
> http://www.sqlite.org/lang_transaction.html
> 
> A deferred transaction doesn't do anything until it first accesses the file. 
> Once it does then it will lock out any writers.
> 
> "Deferred means that no locks are acquired on the database until the database 
> is first accessed. Thus with a deferred transaction, the BEGIN statement 
> itself does nothing to the filesystem. Locks are not acquired until the first 
> read or write operation. The first read operation against a database creates 
> a SHARED lock and the first write operation creates a RESERVED lock."
> 
> 
> -----Original Message-----
> From: sqlite-users [mailto:sqlite-users-boun...@mailinglists.sqlite.org] On 
> Behalf Of Gwendal Roué
> Sent: Tuesday, July 18, 2017 9:10 AM
> To: SQLite mailing list
> Subject: [sqlite] Possible inaccuracy in "Isolation In SQLite" paper
> 
> Hello all,
> 
> The following sentence in https://www.sqlite.org/isolation.html does not 
> exactly describe the behavior of SQLite (since many versions):
> 
>> In WAL mode, SQLite exhibits "snapshot isolation". When a read transaction 
>> starts, that reader continues to see an unchanging "snapshot" of the 
>> database file as it existed at the moment in time when the read transaction 
>> started. Any write transactions that commit while the read transaction is 
>> active are still invisible to the read transaction, because the reader is 
>> seeing a snapshot of database file from a prior moment in time.
> 
> 
> I'll exhibit the inaccuracy below.
> 
> Meanwhile, "snapshot isolation" is a tremendous feature of SQLite. Not only 
> does it grant any read-only connection that opens a deferred transaction an 
> immutable and consistent view of the database. But when you can guarantee 
> that there is a single writer connection, snapshot isolation allows *precise 
> scheduling*, such as blocking the writer connection until a reader has 
> established snapshot isolation. With such precision, one can exactly control 
> what's available to a reader, while not blocking the writer longer than 
> necessary.
> 
> And this is where the documentation paragraph starts becoming inaccurate. For 
> the simplicity of the argument, I'll execute statements sequentially from two 
> connections W and R. To reproduce, just open two shells, and execute 
> statements in the following order:
> 
> $ sqlite3 /tmp/snapshotisolation.sqlite
> SQLite version 3.16.0 2016-11-04 19:09:39
> W> PRAGMA journal_mode=wal;
> W> CREATE TABLE t(a);
> R> BEGIN DEFERRED TRANSACTION;
> W> INSERT INTO t DEFAULT VALUES;
> R> SELECT COUNT(*) FROM t;
> 1
> 
> This is unexpected. After connection R has started a deferred transaction, it 
> should continue to see an "unchanging snapshot of the database file as it 
> existed at the moment in time when the read transaction started". Obviously, 
> this is not the case, since the insertion performed by W is visible from R 
> even though it has been performed *after* R has started its deferred 
> transaction. The "Any write transactions that commit while the read 
> transaction is active are still invisible to the read transaction" is also 
> flat wrong here.
> 
> If we continue, things behave as expected:
> 
> W> INSERT INTO t DEFAULT VALUES;
> R> SELECT COUNT(*) FROM t;
> 1
> 
> R does not see the new insertion, which means that it indeed lives in an 
> unchanging snapshot. It just happens that the snapshot was not established 
> when the transaction has started, as documented, but *later*. But when?
> 
> After a few experiments, it looks like the snapshot is established on the 
> first select:
> 
> W> PRAGMA journal_mode=wal;
> W> CREATE TABLE t(a);
> R> BEGIN DEFERRED TRANSACTION;
> R> SELECT * FROM sqlite_master LIMIT 1; -- good enough to start the snapshot
> W> INSERT INTO t DEFAULT VALUES;
> R> SELECT COUNT(*) FROM t;
> 0 -- as expected
> 
> If now we stop entering commands by hand in the CLI, and start working with 
> threads, the *precise scheduling* I mention at the beginning of the mail 
> requires to block the writer connection W until the reader connection R has 
> started a deferred transaction, and sqlite3_step() has been any executed once 
> from any select statement. Only then can the writer connection be released, 
> with a absolute control of the content of the reader's snapshot.
> 
> I'm not sure the behavior I've just described can be called a bug. The 
> snapshot is unchanging indeed. When there are several processes connected to 
> the database, a reader can't know whether a change has been performed before 
> its deferred transaction has started, or between the start of the deferred 
> transaction and its first select statement, and therefore should not care at 
> all. With this interpretation, there is nothing wrong in the current behavior 
> of SQLite.
> 
> However, when an application developper is sure that the database has a 
> single writer connection, the question of the content of the snapshot 
> suddenly becomes relevant. And the documentation becomes inaccurate.
> 
> What do SQLite concurrency masters of this mailing list think? Besides that 
> threads are evil, I mean ;-) Shouldn't the documentation be updated?
> 
> Cheers to all,
> Gwendal
> PS: For the record, I've been talking about "precise scheduling" and 
> "absolute control of the content of the snapshot" because they are the 
> necessary conditions for some database observation features such as reloading 
> fresh values from a request as soon as a transaction has modified its 
> content. See https://github.com/RxSwiftCommunity/RxGRDB for some high-level 
> implementations of such feature.
> 
> 
> 
> _______________________________________________
> sqlite-users mailing list
> sqlite-users@mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
> _______________________________________________
> sqlite-users mailing list
> sqlite-users@mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to