我正在努力改进我为工作而写的这个程序。最初我很匆忙,他们不关心表演或任何事情。因此,我做出了一个可怕的决定来查询整个数据库(一个SQLite数据库),然后将结果存储在列表中以供我的函数使用。但是,我现在正在考虑将每个函数都线程化,并让函数只查询它需要的数据库部分。有~25个功能。我的问题是,这样做安全吗?此外,是否可以拥有多个并发连接?我只会从数据库中提取信息,永远不会插入或更新。
答案 0 :(得分:0)
我向他描述的方式 [*] 是让每个并发线程打开自己与数据库的连接,因为每个连接一次只能处理一个查询或修改。然后,具有连接的线程组可以轻松地执行并发读取。如果许多并发写入导致严重问题导致过多的阻塞或无法获取锁定,那么你就会超出SQLite为你做的事情(并且应该考虑像PostgreSQL这样的基于服务器的数据库)
请注意,如果更方便的话,你也可以让一个主线程打开工作线程的连接,但是建议(为了你的理智,如果没有别的!)只实际使用每个连接来自一个主题。
[*对于SQLite的正常构建。当然,可以在构建时关闭它。]
答案 1 :(得分:0)
SQLite没有写入并发,但它支持任意多个同时读取的连接。 只需确保每个线程都有自己的连接。
答案 2 :(得分:0)
25个同时连接不是一个聪明的主意。这是一个巨大的数字。
我经常为这个问题创建一个多层设计。我通过一种具有内部缓存的ObjectFactory类将所有请求发送到数据库。 ObjectFactory会将请求转发给ConnectionPoolHandler,并将结果存储在其缓存中。此连接池处理程序使用X个并发连接,但将它们分派给多个线程。
但是,在应用此设计之前必须做一些评论。首先要问自己以下两个问题:
如果第一个问题是否定的,那么您可能会遇到锁定问题。如果你的第二个问题被否定回答,那么应用缓存将非常困难。您甚至可能不希望实现任何缓存。
如果您经常根据唯一引用(例如主键)请求对象,则缓存尤其有用。在这种情况下,您可以将最常用的对象存储在Map中。一个流行的缓存集合是“LRUMap”(“最近最少使用”地图)。这个系列的好处是它可以自动将最常用的对象排列到顶部。同时它具有最大尺寸,并自动从地图中删除很少使用的项目。
缓存的第二个优点是每个对象只存在一次。例如:
在内存中只有一个特定对象有几个优点。
最后但并非最不重要的是Java中存在类似“弱引用”的内容。这些引用实际上可以被垃圾收集器清理。我不确定它是否存在于C#中以及它是如何被调用的。通过实现这一点,您甚至不必关心缓存对象的最大数量,您的垃圾收集器将负责处理它。