Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 线程并发数据库查询安全吗?_C#_Sqlite_Concurrency_Thread Safety - Fatal编程技术网

C# 线程并发数据库查询安全吗?

C# 线程并发数据库查询安全吗?,c#,sqlite,concurrency,thread-safety,C#,Sqlite,Concurrency,Thread Safety,我正在努力改进我为工作而编写的程序。一开始我很匆忙,他们不在乎表现或任何事情。因此,我做出了一个可怕的决定,查询整个数据库(SQLite数据库),然后将结果存储在列表中以供函数使用。然而,我现在正在考虑让我的每个函数线程化,让函数只查询数据库中它需要的部分。有大约25个函数。我的问题是,这样做安全吗?还有,有可能有那么多并发连接吗?我将只从数据库中提取信息,从不插入或更新。我向我描述的方法[*]是让每个并发线程打开自己与数据库的连接,因为每个连接一次只能处理一个查询或修改。这组线程及其连接可以轻

我正在努力改进我为工作而编写的程序。一开始我很匆忙,他们不在乎表现或任何事情。因此,我做出了一个可怕的决定,查询整个数据库(SQLite数据库),然后将结果存储在列表中以供函数使用。然而,我现在正在考虑让我的每个函数线程化,让函数只查询数据库中它需要的部分。有大约25个函数。我的问题是,这样做安全吗?还有,有可能有那么多并发连接吗?我将只从数据库中提取信息,从不插入或更新。

我向我描述的方法[*]是让每个并发线程打开自己与数据库的连接,因为每个连接一次只能处理一个查询或修改。这组线程及其连接可以轻松地执行并发读取。如果在许多并发写中有一个严重的问题,导致过多的阻塞或失败来获取锁,那么您就要达到超过SQLite的要求(并且应该考虑基于服务器的DB型PostgreSQL)。

请注意,如果方便的话,您也可以让主线程打开工作线程的连接,但建议(为了您的理智,如果没有其他事情!)只实际使用一个线程中的每个连接



[*对于SQLite的正常构建。当然,可以在构建时关闭它。]

SQLite没有写入并发性,但它支持任意多个同时读取的连接。
只需确保每个线程都有自己的连接。

25同时连接不是一个明智的想法。这是一个巨大的数字

我通常为这个问题创建一个多层设计。我通过一种具有内部缓存的ObjectFactory类将所有请求发送到数据库。ObjectFactory将请求转发给ConnectionPoolHandler,并将结果存储在其缓存中。此连接池处理程序使用X个同时连接,但将它们分派给多个线程

但是,在应用此设计之前,必须进行一些说明。你首先要问自己以下两个问题:

  • 您的应用程序是唯一有权访问此应用程序的应用程序吗 数据库
  • 您的应用程序是唯一修改此数据库中数据的应用程序吗
如果第一个问题是否定的,那么您可能会遇到锁定问题。如果第二个问题的答案是否定的,那么应用缓存将非常困难。您甚至可能不希望实现任何缓存

当您经常基于唯一引用(如主键)请求对象时,缓存尤其有趣。在这种情况下,可以将最常用的对象存储在地图中。一个流行的缓存集合是“LRUMap”(“最近使用最少的”映射)。此集合的好处是,它会自动将最常用的对象排列到顶部。同时,它有一个最大大小,并自动从地图中删除很少使用的项目

缓存的第二个优点是每个对象只存在一次。例如:

  • 从数据库中提取员工
  • ObjectFactory将结果集转换为实际的对象实例
  • ObjectFactory立即将其存储在缓存中
  • 过了一会儿,一群员工使用SQL“…where name”语句获取,比如“John%”
  • 在将结果集转换为对象之前,ObjectFactory首先检查这些记录的ID是否已经存储在缓存中
  • 找到匹配项!啊哈,不需要重新创建此对象
  • 在内存中只有一次特定对象有几个优点


    最后但并非最不重要的一点是,在Java中有类似“弱引用”的东西“。这些引用实际上可以由垃圾收集器清除。我不确定它是否存在于C#中,以及它的名称。通过实现这一点,您甚至不必关心缓存对象的最大数量,您的垃圾收集器将负责处理它。

    请参阅:这主要是SQLite方面的问题,我最近也在处理这些问题,您可以将其作为服务器或进程运行。也许值得一看。