setWriteAheadLoggingEnabled method not available in Sqlcipher for Android

Hi @developernotes

I see that

writableDatabase.beginTransactionNonExclusive();   setWriteAheadLoggingEnabled(true);

are not available as part of Sqlcipher for Android, but Is there any specific reason why these methods are not available as we are using them in our exisitng project for concurrent transactions. I suspect there could be performance issues as we are dealing with multiple of thousands of records. Please suggest

Hello @vinay_kumar

The SQLiteDatabase::beginTransactionNonExclusive() and SQLiteOpenHelper::setWriteAheadLoggingEnabled() methods were added in API 11, SQLCipher for Android uses an older snapshot of the android.database.sqlite package which allows for targeting down to Android 2.1. You can manually invoke these via SQL commands using rawExecSQL.

oh okay. Thanks for the tip.

Please confirm that

beginTransactionNonExclusive(); is equivalent to

rawExecSQL("PRAGMA database.locking_mode = NORMAL");`  

and

setWriteAheadLoggingEnabled() is equivalent to

rawExecSQL("PRAGMA journal_mode=WAL;");

Hello @AVD

In this case it is best to verify the source to understand the behavior of a different library. It appears that beginTransactionNonExclusive() ends up calling this, so they are issuing a BEGIN IMMEDIATE; command. The call to setWriteAheadLoggingEnabled() appears to end up calling this with a value of WAL.

Hi, @developernotes
I too use SqlCipher and GreenDao as a ORM. Now I can’t enable Write Ahead Logging mode. SqlCipher and GreenDao haven’t enableWriteAheadLogging() function. And I checked 2 variants:

  1. rawExecSQL("PRAGMA journal_mode=WAL;");
    but I get an exception that

cannot change into wal mode from within a transaction: PRAGMA journal_mode = WAL
i.e i can’t execute PRAGMA command in transaction.

  1. setWriteAheadLoggingEnabled(true); function of OpenHelper. But it doesn’t help.
    Or Do I do something incorrect? How can i enable wal mode? Help, please!

Hi @nura_zhakenger

If you are using the current released version of SQLCipher for Android, you can just execute the following:

PRAGMA journal_mode = wal;

However, as you mentioned, you will not be able to do this while you are in a transaction. You might consider using the SQLiteDatabaseHook::postKey operation to enable WAL mode following the opening of a database connection.

We will be including direct API support for enabling WAL mode in the next release of SQLCipher for Android.

Hello, @developernotes. Thanks for feedback! I tried through SQLiteDatabaseHook::postKey and works fine! After test I noticed that it works when database file is exists and while opening of a database, but when database file doesn’t exists and while creating it I get exception that database is locked at the line: database.rawExecSQL(“PRAGMA journal_mode = WAL”);

Hi @nura_zhakenger

Are you able to run the SQLCipher for Android test suite? We have several tests that operate under WAL mode and verify behavior, such as this for example. Does that behavior differ from the way your application operates? Keep in mind, our call to enableWriteAheadLogging is really adjusting the journal mode similar to what you have above.