Berkeley-DB:多个数据库上的原子事务
Posted
技术标签:
【中文标题】Berkeley-DB:多个数据库上的原子事务【英文标题】:Berkeley-DB: Atomic transactions over multiple databases 【发布时间】:2014-04-14 06:14:08 【问题描述】:我想在我的应用程序中使用不同的 Berkeley-DB 数据库来存储不同类别的对象。单个数据库中的事务可以使用 DbTxn::commit 原子地完成。但是,如果我使用多个数据库,我必须创建多个事务(每个数据库一个),对吗?在这种情况下,如果提交第一个成功但第二个失败,有没有办法回滚已经提交的第一个事务? (据我了解 DbTxn::abort,在事务提交后就不能再使用了。)
有没有办法实现跨多个数据库的原子事务?
【问题讨论】:
【参考方案1】:如果您使用多个数据库,则不必创建多个事务。通过使用单个事务,您可以对多个 DB 进行操作。
有关 Db::Open() 的文档,请参阅 this link。
它具有“DbTxn *txnid”参数。您可以指定 DB_ENV->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
【讨论】:
以上是关于Berkeley-DB:多个数据库上的原子事务的主要内容,如果未能解决你的问题,请参考以下文章