4

例如,LevelDB不支持多语句事务。我在某处读到您必须在“事务层”中处理这些问题。

这个层必须做什么才能将事务支持添加到不支持事务的较低级别的库中?

4

2 回答 2

2

定义事务的方法有很多种,实现它们的方法也有很多种。事务的一个共同属性是它是 ACID:

  • 原子性- 全有或全无。一个数据库事务的所有任务都必须完成;如果由于任何可能的原因不完整,则必须中止数据库事务。
  • 一致性- 可序列化和完整性。在数据库事务之前和之后,数据库必须处于一致或合法的状态。这意味着数据库事务不能破坏数据库完整性约束。
  • 隔离数据库事务执行期间使用的数据在执行完成之前不得被另一个数据库事务使用。因此,在事务成功提交之前,不完整事务的部分结果一定不能用于其他事务。这也意味着一个事务的执行不受其他并发事务的数据库操作的影响。
  • 持久性 即使在事务完成后发生系统故障,事务的所有数据库修改都将成为永久性的。

一个事务可能有几种状态:

  • 活动状态:分为两个阶段。初始阶段:数据库事务在其语句开始执行时处于此阶段。部分提交阶段:数据库事务在其最终语句执行完毕后进入此阶段。在这个阶段,数据库事务已经完成了它的执行,但是事务仍然有可能被中止,因为执行的输出可能会暂时留在主内存中——像硬件故障这样的事件可能会擦除输出。
  • 失败状态:数据库事务由于硬件或程序错误而无法正常执行时进入失败状态)。
  • 中止状态:如果数据库事务确定数据库事务失败,则进入中止状态。中止的事务必须对数据库没有影响,因此它对数据库所做的任何更改都必须撤消,或者在技术术语中,回滚。当已中止的事务回滚时,数据库将返回其一致状态。DBMS 的恢复方案负责管理事务中止。
  • 已提交状态:数据库事务在成功完成执行后已将足够的信息写入磁盘时进入已提交状态。在这种状态下,已经将大量信息写入磁盘,以至于交易产生的影响无法通过中止来撤消;即使发生系统故障,提交事务所做的更改也可以在系统重新启动时重新创建。

LevelDB 不支持事务,但它确实具有一些 ACID 属性:

  • 批量写入是原子的。
  • 一致性取决于您。
  • 隔离支持有限。
  • 耐用性是一个可配置的选项。

所以......回到你的问题:

问:

这个层必须做什么才能将事务支持添加到不支持事务的较低级别的库中?

答: 这取决于您如何定义交易。如果您使用上述属性定义事务并且希望事务是 ACID,那么您必须弄清楚 LevelDB 是否可能(大多数 ACID 属性已集成),然后您必须围绕 LevelDB 编写一个包装器,以确保正确维护事务的状态。但是,我不完全确定仅包装器就可以做到这一点,因此您可能必须实际获取源代码并对其进行修改以真正支持事务。

于 2012-01-27T16:55:58.560 回答
2

鉴于您的数据库是单线程的,您可以执行以下操作:

  1. 使用 leveldb 批处理功能:创建一个新密钥,而不是覆盖旧密钥。还记录密钥的旧值和新值。

  2. 如果此时数据库崩溃,则查找日志记录并通过将作为事务一部分的键重述为其旧值来回滚事务。删除日志以完成回滚。

  3. 如果事务已提交,请删除旧键并删除日志条目以完成提交。

然后你有一个使用多个版本的单线程键/值存储的事务。

如果数据库是多线程的,则必须使用 MVCC(请参阅 Yahoo 的 Omid、PostgreSQL、Wiredtiger、bsddb...)和诸如精确可序列化快照隔离 (PSSI) 之类的东西。

于 2015-08-21T21:15:33.003 回答