在不同的线程(QT)上同时打开多个SQLite数据库实例

6

同时使用多个不同线程的开放式连接有问题吗?

从我所了解的来看,默认情况下是线程安全的,但这样做是否会影响性能而非提高它?

2个回答

2
拥有多个连接并不是问题,唯一需要记住的是SQLite不支持多个写事务的并发。从SQLite网站上可以看到:

SQLite支持无限数量的同时读取者,但它只允许在任何时刻只有一个写入者。对于许多情况来说,这不是问题。写入者排队。每个应用程序快速地完成其数据库工作并继续进行,没有锁定持续时间超过几十毫秒。但是有些应用程序需要更多的并发性,这些应用程序可能需要寻找另一种解决方案。

SQLite是一种“非典型”的数据库管理系统:实际上它是一个库,提供了SQL作为访问简单的“文件式数据库”的语言和其他几个DBMS的功能。例如,它没有真正的并发控制(它使用操作系统函数来锁定db文件)。
因此,如果您需要并发插入到数据库中,您应该使用其他东西,例如PostgreSQL

这是否意味着我不能在不同的线程上进行插入/更新操作? - Stephen H. Anderson
是的,您不能进行并发修改。请查看我的更新答案。 - Renzo
@Renzo,这是错误的:你可以在不同的线程中写入数据库,但不能同时进行。一种方法是使用互斥锁,从不同的线程将共享数据发布到数据库中。 - t3ft3l--i
@Renzo 并发是指不同线程同时进行的操作。当然,SQLite不支持同时进行多线程操作,但可以使用锁作为互斥体来组织共享数据。而主要问题并不是关于SQLite的多个事务。 - t3ft3l--i
1
您可以在线程中使用插入等操作。只有您应该知道,即使线程操作不同的数据,它们也会被序列化。但是,它们会被系统自动序列化,因此您无需更改程序。此外,您仅有少量线程的事实意味着您不会注意到应用程序的任何特定性能损失。 - Renzo
显示剩余3条评论

1

文档中写到:

一个连接只能在创建它的线程中使用。在不同的线程之间移动连接或创建查询不受支持。

此外,QSqlDrivers 使用的第三方库可能会对在多线程程序中使用 SQL 模块施加进一步限制。请参阅您的数据库客户端手册以获取更多信息。

这意味着您必须创建连接到与父线程链接的数据库。在 QSqlDatabase 类的文档中,您可以看到其描述:

QSqlDatabase类表示与数据库的连接。

QSqlDatabase类提供通过连接访问数据库的接口。QSqlDatabase的一个实例表示连接。连接通过其中一个受QSqlDriver派生的支持的数据库驱动程序之一提供对数据库的访问。

调用其中一个静态的addDatabase()函数来创建连接(即QSqlDatabase的一个实例),在该函数中你需要指定要使用的驱动程序或驱动程序类型(即将访问哪种类型的数据库)以及一个连接名称。

使用静态的addDatabase()函数是创建连接的方法。

但正如Renzo所说,SQLite不支持同时进行多个写事务。因此,你需要一些机制(包装器)来同步线程,例如使用低级别的互斥锁或类似的任务队列等。更多信息请参见文档


1
正如我在我的回答评论中所写的那样,实际上没有必要显式地同步线程。SQLite会自动进行序列化。 - Renzo
@Renzo,所以需要配置SQLite。 - t3ft3l--i

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接