Searcing SO for similar questions, the consensus seems that you will need to do the locking yourself. Some answers pointed to passing around the same SqliteConnection
object to all threads that do the writing. Though I don't think that will solve the problem.
I would suggest rethinking the concurrent write/read. I am assuming that your threads do some work and then save to the db within that thread. I would rewrite it such that the threads do some work AND return the output. The process of saving data to db needn't be coupled with the process of performing the work. Concurrent reads should work without change as the lock is a shared
one for reads. Sure, there could be a scenario where the write and the reads happen at the same time. In which case the error would pop up again.
I think it might be simpler to just use a global lock object
and use that to sync/serialize all your writes/reads. However, the moment you do that, you have effectively made db access single threaded. This is one of those questions where the answer depends on you what your end goal is.
Btw, shouldn't you be using a database level transaction instead of an application level? Something like http://msdn.microsoft.com/en-us/library/86773566.aspx
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand command = connection.CreateCommand();
SqlTransaction transaction;
// Start a local transaction.
transaction = connection.BeginTransaction("SampleTransaction");
// Must assign both transaction object and connection
// to Command object for a pending local transaction
command.Connection = connection;
command.Transaction = transaction;
try
{
command.CommandText =
"Insert into Region (RegionID, RegionDescription) VALUES (100, 'Description')";
command.ExecuteNonQuery();
command.CommandText =
"Insert into Region (RegionID, RegionDescription) VALUES (101, 'Description')";
command.ExecuteNonQuery();
// Attempt to commit the transaction.
transaction.Commit();
Console.WriteLine("Both records are written to database.");
}
catch (Exception ex)
{
Console.WriteLine("Commit Exception Type: {0}", ex.GetType());
Console.WriteLine(" Message: {0}", ex.Message);
// Attempt to roll back the transaction.
try
{
transaction.Rollback();
}
catch (Exception ex2)
{
// This catch block will handle any errors that may have occurred
// on the server that would cause the rollback to fail, such as
// a closed connection.
Console.WriteLine("Rollback Exception Type: {0}", ex2.GetType());
Console.WriteLine(" Message: {0}", ex2.Message);
}
}
}