database - 多线程应用程序中的单个连接VS共享数据库连接?
问题描述
我目前正在支持一个多线程应用程序(Delphi 10.4),它生成大约 20 个线程来从远程打卡时钟中获取数据并将其输入数据库表(所有线程都相同),但是通过让每个线程生成它自己的 (MSADO) 连接在构造上。现在,虽然这确实使应用程序线程安全,因为它们不共享资源,但在效率方面,建立一个线程将共享的连接并通过使用 TMonitor、关键部分或其他东西确保线程安全是否是一个更好的主意?相似的?
解决方案
取决于您对数据库的写入量。如果您使用单个连接并且仍然为每个线程使用一个插入语句,那么您将无法解决任何问题。此外,由于等待打开数据库连接的线程之间的同步,您的应用程序会变慢。
要以正确的方式执行此操作,您将需要在生产者(从打卡时钟获取数据的线程)和消费者(数据库写入器线程)之间应用类似producer
-模式的队列。consumer
一旦阅读器线程获取数据,它将:
- 锁定队列访问
- 将其添加到队列中。
- 解锁队列
一旦编写器线程开始运行,它将:
- 锁定队列访问
- 从队列中收集所有数据,
- 从队列中删除消息
- 解锁队列
INSERT
为队列中的所有行准备单个语句- 在数据库上执行事务
- 短时间休眠(允许其他线程工作)
这不是数据安全的方法,因为如果从队列中删除的数据和提交到数据库的数据之间出现故障,数据将会丢失。
如您所见,这是一种更复杂的方法,因此如果您没有遇到数据库拥塞,则不值得使用单连接。
注意:还有一种方法可以使用数据库连接池,这是在这种情况下最常用的模式。使用 DB 池,在尝试读/写数据库的大量线程之间共享较少数量的连接。
推荐阅读
- javascript - 根据索引从两个单独的数组中创建一个对象
- c# - 有条件地显示 WPF 树视图级别
- java - 如何在 HSQLDB 中定义 Out CURSOR 并通过 Java/Junit 访问它
- c# - unity3d php图片上传
- r - 有没有返回整数值的 sign() 替代方法?
- vue.js - 在“vue”中找不到“导出”“Vue”
- python - 使用 pandas 对 sqlite 3 表进行部分更新
- android - 在与 Tizen 模拟器相同的 Windows PC 上运行 Android 模拟器?
- asp.net-core - 从 Blazor 中的父组件传递时如何在子组件中显示数据?
- odoo - 无法创建不平衡的日记帐分录。ID:差异借方 - 贷方尝试创建发票行时出错