Igor Tandetnik wrote:
> On 2/4/2014 11:57 AM, Yuriy Kaminskiy wrote:
>> Phew. Do you speak C? Enjoy.
>>
>>      printf("insert...\r"); fflush(stdout);
>>      for(i = 0; i < 1000; i++) {
>>     rc = sqlite3_bind_int(ins_sth, 1, i);
>>     assert(rc == SQLITE_OK);
>>     rc = sqlite3_step(ins_sth);
>>     assert(rc == SQLITE_DONE);
> 
> As expected, I get an assertion here, on 925th iteration of the loop.
> Are you seeing something different?

Yes. I see only 10-second pauses on 252th, 364th, etc iterations, and *no*
assertion failures.
After completion, ttt.db3 contains exactly 1000 records with 0...999, without
any misses.
Same after I increased number of iterations to 10000.

FWIW, if I swap two "COMMIT" lines, it results in assertion failure (as
expected) on sql_exec(dbh, "COMMIT"), so assertion enabled and error detection
works.

> The only thing is that rc == SQLITE_IOERR at this point, and not
> SQLITE_BUSY as I stated earlier. If I enable extended result codes (see
> sqlite3_extended_result_codes), then the error is SQLITE_IOERR_BLOCKED.
> This is actually documented at
> http://www.sqlite.org/c3ref/busy_handler.html :

grep for SQLITE_IOERR_BLOCKED in source code have not shown anything but false
positives. There are some code that *checks* for IOERR_BLOCKED, but there are no
code that can *set* IOERR_BLOCKED. But maybe I've overlooked something,
corrections welcomed.

> The SQLITE_BUSY error is converted to SQLITE_IOERR_BLOCKED when SQLite
> is in the middle of a large transaction where all the changes will not
> fit into the in-memory cache. SQLite will already hold a RESERVED lock
> on the database file, but it needs to promote this lock to EXCLUSIVE so
> that it can spill cache pages into the database file without harm to
> concurrent readers. If it is unable to promote the lock, then the
> in-memory cache will be left in an inconsistent state and so the error
> code is promoted from the relatively benign SQLITE_BUSY to the more
> severe SQLITE_IOERR_BLOCKED. This error code promotion forces an
> automatic rollback of the changes. See the CorruptionFollowingBusyError
> < http://www.sqlite.org/cvstrac/wiki?p=CorruptionFollowingBusyError >
> wiki page for a discussion of why this is important.

I also verified that sqlite3_get_autocommit is 0 before sql_exec("COMMIT"), and
1 afterwards, so no "automatic rollback" either.

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

Reply via email to