C++ ODB使用踩坑记录(一)

1.查询条件拼接是注意字符串头是否为空

# query字符串头不为空
std::string query = "select * from Users where id =1";
typedef odb::result<ODBORM::Users> result;
result rs(db->query<ODBORM::Users>(query));
# 如果开了odb的 odb::core::transaction t(db->begin());
#t.tracer(odb::stderr_full_tracer);
# 在终端看到这个执行是一个正常的sql:  select * from Users where id =1

# query字符串头为空
std::string query = " select * from Users where id =1";
#这个时候会在终端看到这个执行是一个在前面拼接了一个where 的sql: where select * from Users where id =1

2.根据需要创建不同表的schema,用于创建在不同的数据库中

/*odb 使用时要先编译相应的头文件xxx.h,生成xxx-odb.cxx,xxx-odb.ixx,xxx-odb.hxx
目前有个需求 a.h 描述的表生成在a.db, b.h描述的表生成在b.db
*/
# 首先编译时指定schema-name
/*cd $(ProjectDir)src\odbormtype\a\ && odb.exe --std c++11 --database sqlite --generate-query  --generate-schema --schema-name a -I ../../../.. a.h
cd $(ProjectDir)src\odbormtype\b\ && odb.exe --std c++11 --database sqlite --generate-query  --generate-schema --schema-name b -I ../../../.. b.h
*/

# 代码中  
auto db = std::make_shared<odb::sqlite::database>("a.db",
        SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
odb::core::transaction t(db->begin());
odb::schema_catalog::create_schema(*db, "a");
t.commit();

auto db = std::make_shared<odb::sqlite::database>("b.db",
        SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
odb::core::transaction t(db->begin());
odb::schema_catalog::create_schema(*db, "b");
t.commit();

3.odb中声明了一个事务,只有这个事务commit的了才能启动另外的事务,即使不同的数据库事务也不可以交织在一起。但是可以声明同一个事务,跨数据库操作,在该事务中一起提交

/*In the above example the employee class will be stored in the 'main'
database (this is the name given by SQLite to the first opened database).
The employer class will be stored in the 'extra' database. Here is how
we can attach the 'extra' database:*/

odb::sqlite::database db ("main.db"); // main -> main.db
db.execute ("ATTACH DATABASE extra.db AS extra");

employee ee;
employer er;

transaction t (db.begin ());
db.persist (ee);  // Goes to main.db.
db.persist (er);  // Goes to extra.db.
t.commit ();

参考URL:[odb-users] Handling Multiple Databases/Threads in ODB

4.在connection中execute执行set pragam相关命令

db->connection()->execute("PRAGMA journal_mode=WAL");

5.出现timeout或者deadlock使用retry方案,如果频繁出现或者拆分库表

bool retryDbTransaction(std::function<void()> &func) {
  int max_retries = 10;
  for (unsigned short retry_count(0);; retry_count++) {
    try {
      // odb::core::transaction t(projectDb->begin());
      func();
      return true;
    } catch (const odb::recoverable &e) {
      if (retry_count > max_retries) {
        return false;
      } else {
        continue;
      }
    } catch (const odb::timeout &e) {
      if (retry_count > max_retries) {
        return false;
      } else {
        continue;
      }
    }
  }
}

6.查询也会使用事务,避免查询影响写,可以考虑使用wal机制

参考url:Write-Ahead Logging

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值