Unexpected persistence of PRAGMA journal_mode after transaction rollback in expo-sqlite
0 reputation · 19 Apr 2026, 02:57 UTC
0 reputation · 19 Apr 2026, 02:57 UTC
When using expo‑sqlite to run schema migrations inside a transaction, developers rely on the BEGIN … COMMIT/ROLLBACK wrapper to revert CREATE, ALTER, or DROP statements on error.
However, certain SQLite pragmas such as PRAGMA journal_mode=WAL are not undone by a ROLLBACK, which can leave the database in a state that differs from the pre‑migration configuration.
The goal is to confirm whether expo‑sqlite automatically rolls back these non‑transactional pragmas when a migration transaction fails, and to understand the practical impact on migration safety across Expo SDK versions.
Does expo‑sqlite roll back PRAGMA journal_mode changes issued inside a transaction when the transaction is rolled back? If not, how does this affect the consistency of the database after a failed migration? What pattern should be used to isolate non‑rollbackable pragmas from migration steps to guarantee a clean rollback?
35275 reputation · 19 Apr 2026, 12:27 UTC
In expo‑sqlite the PRAGMA journal_mode statement is executed directly against the underlying SQLite engine. SQLite treats PRAGMA changes as part of the connection state, not as part of a transaction. Therefore a ROLLBACK only restores data rows and, in some cases, schema objects, but it never reverts a PRAGMA that was executed inside the same BEGIN/COMMIT block.
PRAGMA journal_mode=WAL inside a transaction and then issuing ROLLBACK keeps the database in WAL mode.PRAGMA journal_mode; after the rollback will return wal and the -wal and -shm sidecar files will remain on disk.Data integrity is preserved because the rollback undoes all DML/DDL changes. However, the operational mode of the database file is altered permanently, which can affect:
PRAGMA wal_checkpoint(TRUNCATE) or a new PRAGMA journal_mode=DELETE is issued.await db.execAsync('PRAGMA journal_mode=WAL');
await db.execAsync('BEGIN');
// migration statements
await db.execAsync('COMMIT');
This guarantees the PRAGMA is applied regardless of transaction outcome.
await db.execAsync('PRAGMA journal_mode=DELETE');
SAVEPOINT that you explicitly release or rollback, but remember that PRAGMAs still persist.
PRAGMA journal_mode; and check the mode.
*.wal and *.shm files in the database directory.
If you are using a very old Expo SDK (pre‑SDK 49) that bundles SQLite < 3.36, the exact behavior may differ slightly. Knowing the SDK version will help confirm whether the same pattern applies.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.