【问题标题】:Berkeley-DB: Atomic transactions over multiple databasesBerkeley-DB:多个数据库上的原子事务
【发布时间】:2014-04-14 06:14:08
【问题描述】:

我想在我的应用程序中使用不同的 Berkeley-DB 数据库来存储不同类别的对象。单个数据库中的事务可以使用 DbTxn::commit 原子地完成。但是,如果我使用多个数据库,我必须创建多个事务(每个数据库一个),对吗?在这种情况下,如果提交第一个成功但第二个失败,有没有办法回滚已经提交的第一个事务? (据我了解 DbTxn::abort,在事务提交后就不能再使用了。)

有没有办法实现跨多个数据库的原子事务?

【问题讨论】:

    标签: c++ database berkeley-db


    【解决方案1】:

    如果您使用多个数据库,则不必创建多个事务。通过使用单个事务,您可以对多个 DB 进行操作。

    有关 Db::Open() 的文档,请参阅 this link

    它具有“DbTxn *txnid”参数。您可以指定 DB_EN​​V->txn_begin() API 返回的事务 id。所以在打开数据库之前,应该获取一个事务ID。

    仔细阅读给定文档链接中参数“txnid”下的注释。

    请注意,您不应在 Db::open() API 中指定 DB_AUTO_COMMIT 标志。取而代之的是,您将为要操作的所有 DB 的参数“txnid”指定相同的事务 ID。这样就可以实现跨多个数据库的原子事务。

    【讨论】:

    • 谢谢,我不知道这种可能性!不幸的是,我使用的代码在启动时只创建一次数据库,并将它们重新用于所有事务。更频繁地创建和销毁 Db 对象会损害性能吗?据推测,它至少会立即刷新到磁盘?
    • 是的,重复调用 Db::open() 和 Db::close() 会影响性能。还有另一种方法可以实现您想要的。为 'txnid' 参数调用带有 NULL 的 Db::open() 并将 DB_AUTO_COMMIT 指定给 'flag' 参数。保持打开 Db 句柄。使用 DB->cursor() 创建一个游标。为 'txnid' 参数指定一个有效的 txn。为每个 DB 创建每个游标,并为所有游标指定相同的 txn。使用 DBcursor->get() 和 DBcursor->put() 进行读/写操作。这样,您可以避免重复打开和关闭数据库。因此,也可以避免性能瓶颈。
    • 这正是我想要的!谢谢!
    【解决方案2】:

    通常,您需要分布式事务管理器之类的东西,完整的答案充满了书籍。请参阅“The Berkeley DB Book”,第 9 章,“分布式事务和数据分发策略”,ISBN-10:1-59059-672-2

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多