多线程应用程序中的个人连接 VS 共享数据库连接?

Individual connections VS shared DB connection in a multi-thread app?

我目前正在支持一个多线程应用程序 (Delphi 10.4),它生成大约 20 个线程以从远程打卡时钟获取数据并将其输入数据库 table(同一个对于所有线程),但通过让每个线程在构造时生成自己的 (MSADO) 连接来实现。现在虽然这确实使应用程序线程安全,因为它们不共享资源,但是通过使用 TMonitor、关键部分或其他东西建立一个线程将共享的连接并确保线程安全是一个更好的想法吗?相似?

取决于您对数据库的写入量。如果您使用单个连接并且仍然为每个线程使用一个插入语句,那么您没有解决任何问题。此外,由于等待数据库连接的线程之间的同步,您的应用程序将变慢。

要以正确的方式执行此操作,您需要应用类似 producer - consumer 的模式,在生产者(线程从打孔器获取数据)之间有一个队列-clock)和消费者(数据库写入线程)。

一旦 reader 线程获取数据,它将:

  1. 锁定队列访问
  2. 将其添加到队列中。
  3. 解锁队列

编写器线程启动后 运行,它将:

  1. 锁定队列访问
  2. 从队列中收集所有数据,
  3. 从队列中删除消息
  4. 解锁队列
  5. 为队列中的所有行准备单个 INSERT 语句
  6. 在数据库上执行事务
  7. 休眠一小段时间(让其他线程工作)

这不是数据安全的方法,因为如果从队列中删除的数据与提交到数据库的数据之间出现故障,数据将会丢失。

如您所见,这是一种更复杂的方法,因此如果您没有遇到数据库拥塞,则不值得使用单连接。

Note: There is also approach to use a pool of DB connections which is the most used pattern in this cases. With the DB pool, a smaller number of connections are shared among large number of threads trying to read/write the database.