【问题标题】:Multiple SQLite database instances open at the same time on different Threads (QT)在不同的线程(QT)上同时打开多个 SQLite 数据库实例
【发布时间】:2015-07-20 20:53:52
【问题描述】:

从不同线程同时使用多个打开的连接有什么问题吗?

据我所知,默认情况下它是线程安全的,但是,这会损害性能而不是提高性能吗?

【问题讨论】:

    标签: performance qt sqlite optimization thread-safety


    【解决方案1】:

    拥有多个连接不是问题,唯一需要记住的是SQLite不支持多个写入事务的并发。来自 SQlite site

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

    SQLite 是一个“非典型”数据库管理系统:实际上,它是一个库,它提供 SQL 作为语言来访问简单的“文件中的数据库”以及 DBMS 的一些其他功能。例如,它没有真正的并发控制(它使用操作系统函数来锁定 db 文件)。

    因此,如果您需要并发插入数据库,则应该使用其他内容,例如 PostgreSQL

    【讨论】:

    • 这是否意味着我不能在不同的线程上进行插入/更新?
    • 是的,您不能同时进行修改。请参阅我的更新答案。
    • @Renzo,它错了:您可以在不同的线程上写入数据库,但不能同时写入。一种方法是使用互斥体并将共享数据从不同线程发布到数据库。
    • @t3ft3l--i,怎么了? SQLite 手册?或者并发是在操作系统级别完成的事实?我在 DBMS 级别谈论并发。 SQLite 的并发在 DBMS 级别不是真正的并发。这很简单。在“真正的”DBMS 中,您每秒可以有数千个写入事务,而在 SQLite 中则不会。
    • 您可以在您的线程中使用插入等。只有你应该知道,即使线程对不同的数据进行操作,它们也会被序列化。但是,它们会由系统自动序列化,因此您不必更改程序。此外,您只有几个线程这一事实意味着您不会注意到应用程序有任何特别的性能损失。
    【解决方案2】:

    documentation 说:

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

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

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

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

    QSqlDatabase 类提供了访问数据库的接口 通过一个连接。 QSqlDatabase 的一个实例表示 联系。该连接通过以下方式之一提供对数据库的访问 支持的数据库驱动,从 QSqlDriver 派生。

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

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

    但正如 Renzo said SQLite 不支持同时多个写入事务。所以你需要一些机制(包装器)来同步线程,比如使用低级互斥锁或类似的东西的任务队列。更多信息请访问docs

    【讨论】:

    • 正如我在回答的评论中所写的,实际上不需要显式同步线程。序列化由 SQLite 自动完成。
    • @Renzo,所以需要配置SQLite
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多