Skip to content

Commit 2fe8e66

Browse files
Correct: Minor bug fix to address READ-ONLY lock file error on StartUp
1 parent e57c3c3 commit 2fe8e66

2 files changed

Lines changed: 37 additions & 12 deletions

File tree

EntityFrameworkCore.Sqlite.Concurrency/EFCore.Sqlite.Concurrency.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
<!-- Core Package Identity -->
1313
<PackageId>EntityFrameworkCore.Sqlite.Concurrency</PackageId>
14-
<Version>10.0.3</Version>
14+
<Version>10.0.4</Version>
1515

1616
<!-- Core Metadata for Trust & Recognition -->
1717
<Authors>Mike Gotfryd</Authors>

EntityFrameworkCore.Sqlite.Concurrency/src/SqliteConnectionEnhancer.cs

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Text;
44
using EntityFrameworkCore.Sqlite.Concurrency.Models;
55
using Microsoft.Data.Sqlite;
6+
using Microsoft.Extensions.Logging;
67

78

89
namespace EntityFrameworkCore.Sqlite.Concurrency;
@@ -153,15 +154,36 @@ public static void ApplyRuntimePragmas(DbConnection connection, SqliteConcurrenc
153154
{
154155
if (!_initializedDatabases.ContainsKey(dataSource))
155156
{
157+
var logger = options.LoggerFactory?.CreateLogger(nameof(SqliteConnectionEnhancer));
158+
159+
// WAL mode is initialized first and in isolation so that a SQLITE_READONLY
160+
// failure (most commonly SQLITE_READONLY_CANTINIT on Windows when the .db-shm
161+
// file cannot be created or has wrong permissions) is caught and logged as a
162+
// warning rather than crashing the entire interceptor. Without WAL the database
163+
// still functions; concurrent write performance is reduced because reads and
164+
// writes cannot proceed simultaneously.
165+
try
166+
{
167+
using var walCommand = sqliteConnection.CreateCommand();
168+
walCommand.CommandText = "PRAGMA journal_mode = WAL;";
169+
walCommand.ExecuteNonQuery();
170+
}
171+
catch (SqliteException ex) when (ex.SqliteErrorCode == 8) // SQLITE_READONLY
172+
{
173+
logger?.LogWarning(ex,
174+
"Could not enable WAL mode for '{DataSource}' " +
175+
"(SQLITE_READONLY, extended code: {Extended}). " +
176+
"The database will use the default journal mode — concurrent read/write " +
177+
"performance will be reduced. To resolve: ensure the database directory " +
178+
"is writable and delete any stale .db-shm / .db-wal files alongside the " +
179+
"database, then restart the application.",
180+
dataSource, ex.SqliteExtendedErrorCode);
181+
}
182+
156183
try
157184
{
158185
using var initCommand = sqliteConnection.CreateCommand();
159186
initCommand.CommandText = $@"
160-
-- WAL mode: readers and writers can proceed concurrently (readers never block
161-
-- writers and writers never block readers). The WAL file must remain on the
162-
-- same machine as the database — do not use WAL on network filesystems.
163-
PRAGMA journal_mode = WAL;
164-
165187
-- 4 096 bytes aligns with modern OS page sizes (ext4, NTFS, APFS) and is the
166188
-- SQLite recommended default. Changing page_size after data exists has no effect
167189
-- without a VACUUM, so this is a no-op on pre-existing databases.
@@ -183,15 +205,18 @@ public static void ApplyRuntimePragmas(DbConnection connection, SqliteConcurrenc
183205
PRAGMA wal_autocheckpoint = {options.WalAutoCheckpoint};
184206
";
185207
initCommand.ExecuteNonQuery();
186-
187-
_initializedDatabases.TryAdd(dataSource, true);
188208
}
189-
catch
209+
catch (Exception ex)
190210
{
191-
// Ensure we don't leave it marked as initialized if it failed
192-
_initializedDatabases.TryRemove(dataSource, out _);
193-
throw;
211+
logger?.LogWarning(ex,
212+
"One or more database-initialization PRAGMAs failed for '{DataSource}'. " +
213+
"The connection-scoped PRAGMAs (busy_timeout, cache_size, etc.) will still be applied.",
214+
dataSource);
194215
}
216+
217+
// Mark as initialized regardless of partial failures above so that the
218+
// failed PRAGMAs are not retried on every subsequent connection open.
219+
_initializedDatabases.TryAdd(dataSource, true);
195220
}
196221
}
197222
}

0 commit comments

Comments
 (0)