在C ++中异步执行SQL查询

时间:2019-10-12 22:39:18

标签: c++ sqlite boost boost-asio stdasync

我有一个应用程序,可将数据读入地图并将其写入sqlite数据库。该应用程序执行许多其他操作,并且是异步的(使用boost asio),除了写入数据库部分。这是示例伪代码:

struct records;
std::map<int, records> list;
void read() {
    // Dump(read) X records into list
    // If record id doesn't exist, add it. dirty = true
    // If it exists, update all other fields. dirty = true if any fields changed.
}

void writeDB() {
    sqlite3_prepare_v2();
    for(const auto& record : list) { // iterate map
        if(!record.dirty())
            continue;
        sqlite3_bind(); // bind record fields
        sqlite3_step(); // execute sql 
        sqlite3_reset(); // reset
    }
    sqlite3_finalize();
}

main() {
    while(1) {
        read();
        writeDB();
    }
}

我最初的计划是在for循环内产生一个新线程,该线程将并行写入数据库中的每个记录。有两个问题。

1)可能需要实现数据库锁定。

2)sqlite bind(), step() and reset()对同一条语句进行操作。因此,记录必须按顺序写入。

我正在使用C ++ 17.关于使数据库调用异步的任何建议?感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

您不必实现锁定。 SQLite does provide ACID guarantees,这意味着您不必对插入物实施锁定。

话虽这么说,为每个插入操作生成一个线程肯定是多余的。您可以考虑将列表分为若干部分,这些部分等于计算机上的内核数,并执行N个并行循环来插入。但是在我看来,超出此范围的任何内容都可能是过大的。

但不要认为我的话是理所当然的。考虑考虑对您的代码进行检测,并对现在拥有的单线程版本以及可能选择的任何并行实现进行基准测试。您可以测试各种线程数(但请记住,多线程代码性能与可用内核数之间存在关系)以及并发实现:C ++ 17 std并行执行或boost变体等