I am using System.Data.SQLite in .NET and encountering "database is locked" with wal using multiple threads from the same process running simple select statements with (separate) read-only connections. Please see the link below and note the Visual Studio output window when it runs.
https://drive.google.com/open?id=0By9M2uwoQgnKUnN6Z2NoWDZLS2s Here is the bulk of the code in case more helpful than the download: class Program { /// <summary> /// Configure for x64 and hit F5 in Visual Studio /// Check the output window and note "database is locked" /// </summary> /// <param name="args"></param> static void Main(string[] args) { // the db file was copied to bin // note: the db was last opened with wal var dbPath = new FileInfo(Assembly.GetExecutingAssembly().Location).Directory.FullName; var dbFile = Path.Combine(dbPath, "Simple.db3"); var csb = new SQLiteConnectionStringBuilder(); csb.DataSource = dbFile; csb.ReadOnly = true; var connStr = csb.ConnectionString; RunTest(connStr); } private static void RunTest(string connStr) { var f1 = Task.Factory.StartNew(() => DoReadTest(connStr), TaskCreationOptions.LongRunning); var f2 = Task.Factory.StartNew(() => DoReadTest(connStr), TaskCreationOptions.LongRunning); var f3 = Task.Factory.StartNew(() => DoReadTest(connStr), TaskCreationOptions.LongRunning); var f4 = Task.Factory.StartNew(() => DoReadTest(connStr), TaskCreationOptions.LongRunning); Task.WaitAll(new List<Task> { f1, f2, f3, f4 }.ToArray()); } private static void DoReadTest(string connStr) { var untilTime = DateTime.UtcNow.AddSeconds(10); int numRuns = 0; long totalMS = 0; // hammer the db with reads do { var sw = new Stopwatch(); sw.Start(); ReadTestWorker(connStr); numRuns++; totalMS += sw.ElapsedMilliseconds; } while (DateTime.UtcNow < untilTime); Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId} avg ms: { totalMS / numRuns }, Total runs {numRuns }"); } private static void ReadTestWorker(string connStr) { const string sql = "SELECT MAX(Id) AS MaxId FROM TestTable;"; using (var connection = new SQLiteConnection(connStr)) { connection.Open(); using (var cmd = connection.CreateCommand()) { cmd.CommandText = sql; using (var reader = cmd.ExecuteReader()) { while (reader.Read()) { var msg = $"Thread {Thread.CurrentThread.ManagedThreadId} says max id is : {reader[0]}"; //Console.WriteLine(msg); } } } } } } Thank you, Vince