通过System.Data.SQLite和c#多次访问单个SQLite数据库文件

正如我可以从SQLite FAQ中读到的,它支持多个进程读取(SELECT),并且在任何时刻都只支持一个进程编写(INSERT,UPDATE,DELETE)数据库:

SQLite使用读取器/写入器锁来控制对数据库的访问。 当任何进程想要写入时,它必须在更新期间锁定整个数据库文件。 但这通常只需要几毫秒。 其他流程只是等待作者完成然后继续他们的业务

我通过c#使用System.Data.SQLite适配器。

有人可以告诉我PLZ,这个过程到底是怎么回事?

这个过程是否会自动运行,编写SQLiteCommand只会等待另一个SQLiteCommand已经在同一个数据库上执行?

或者它可能会抛出exception? 什么样的?

对不起,我发现没有关于这个机制的信息:)

谢谢。

更新:

我发现post说exception会引发一个特定的错误代码

这个陈述是否正确?

我自己调查过:

我创建了一个示例SQLite数据库c:\123.db ,其中包含一个表包含两个字段的CategoriesID (uniqueidentifier)和Name (nvarchar)。

然后我编写了一些multithreading代码来模拟对数据库的多次写访问(如果使用此代码,请不要忘记向项目添加System.Data.SQLite引用):

 using System; using System.Data.SQLite; using System.Threading.Tasks; namespace SQLiteTest { class Program { static void Main(string[] args) { var tasks = new Task[100]; for (int i = 0; i < 100; i++) { tasks[i] = new Task(new Program().WriteToDB); tasks[i].Start(); } foreach (var task in tasks) task.Wait(); } public void WriteToDB() { try { using (SQLiteConnection myconnection = new SQLiteConnection(@"Data Source=c:\123.db")) { myconnection.Open(); using (SQLiteTransaction mytransaction = myconnection.BeginTransaction()) { using (SQLiteCommand mycommand = new SQLiteCommand(myconnection)) { Guid id = Guid.NewGuid(); mycommand.CommandText = "INSERT INTO Categories(ID, Name) VALUES ('" + id.ToString() + "', '111')"; mycommand.ExecuteNonQuery(); mycommand.CommandText = "UPDATE Categories SET Name='222' WHERE ID='" + id.ToString() + "'"; mycommand.ExecuteNonQuery(); mycommand.CommandText = "DELETE FROM Categories WHERE ID='" + id.ToString() + "'"; mycommand.ExecuteNonQuery(); } mytransaction.Commit(); } } } catch (SQLiteException ex) { if (ex.ReturnCode == SQLiteErrorCode.Busy) Console.WriteLine("Database is locked by another process!"); } } } } 

我的Core2Duo E7500的结果是永远不会出现exception!

看起来SQLite已根据我的需求进行了优化(锁定/解锁非常快,通常只需几毫秒,如SQLite FAQ告诉我们的那样) - 太棒了!

请注意,不需要为SQLiteException检索整数ErrorCode - 您可以使用特殊的枚举ReturnCode字段。 这里描述了所有代码。

希望这些信息对某人有所帮助。