首页 > 解决方案 > 多线程应用程序中的单个连接VS共享数据库连接?

问题描述

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

标签: databasemultithreadingthread-safety

解决方案


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

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

一旦阅读器线程获取数据,它将:

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

一旦编写器线程开始运行,它将:

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

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

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

注意:还有一种方法可以使用数据库连接池,这是在这种情况下最常用的模式。使用 DB 池,在尝试读/写数据库的大量线程之间共享较少数量的连接。


推荐阅读