The documentation for SQLITE_READONLY_ROLLBACK suggests that it will only happen as a result of a previous crash or power failure, where a hot journal is left behind. I'm seeing that error without those events and with a small number of concurrent readers and writers.
In the implementation of SQLite, comments in hasHotJournal() mention the possibility of a false positive (referencing ticket #3883, which I cannot find) and how it will be handled in the playback mechanism after obtaining an exclusive lock. The check for a read-only connection after hasHotJournal() is called, however, happens (and must happen?) before that exclusive lock is acquired. So, it seems like the race-provoked false positive could trigger a false SQLITE_READONLY_ROLLBACK error. If that's right, then for my application's purposes, it works to detect SQLITE_READONLY_ROLLBACK and just try again. I'd like to make sure I'm not missing some other problem in my system, though. Thanks! Matthew