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

2023-11-22

正如我可以读到的SQLite 常见问题解答它支持在任意时刻多进程读取(SELECT)和仅一个进程写入(INSERT、UPDATE、DELETE)数据库:

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

我在用着系统.数据.SQLite通过 c# 的适配器。

有人可以解释一下吗?exactly这个过程是怎么回事?

这个过程会自动进行并写入吗SQLite命令如果有其他写作,将只是等待SQLite命令已经在同一个数据库上执行?

或者也许它会抛出异常?什么样的呢?

抱歉,我没有找到有关此机制的信息:)

谢谢。

UPDATE:

我发现帖子说的是将引发异常具有特定的错误代码

这种说法正确吗?


我亲自调查过:

我创建了一个示例 SQLite 数据库c:\123.db有一张桌子Categories包含两个字段:ID(唯一标识符)和Name(nvarchar)。

然后,我编写了一些多线程代码来模拟对数据库的多次写入访问(不要忘记添加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 上的结果是从未引发异常!

看起来 SQLite 已经足够优化以满足我的需求(锁定/解锁非常快,通常只需要几毫秒,因为SQLite 常见问题解答告诉我们) - 太棒了!

请注意,无需检索整数 ErrorCodeSQLiteException- 你可以使用特殊的枚举ReturnCode场代替。所有代码都有说明here.

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐