使用SimpleDB实现“事务”的方法

时间:2011-12-13 22:42:29

标签: .net amazon-web-services amazon-simpledb

我大部分时间都在使用AWS的SimpleDB,但也希望在多个域(表)中存储一些关键的支付/财务数据。 RDS当然是一个选项,但由于我已经在SimpleDB上有一个不错的层,如果在那一层实现它很简单,我想为什么不这样做。

所以我想,要求:

  • 锁定对事务中涉及的域对象的访问
  • 存储以前版本的对象以便于回滚
  • 检测对“已损坏”或“失败”交易的对象的访问权限,并回滚所涉及的所有内容

由于我可以控制对这些域的所有访问,我认为这一切都是可能的。是否有一种标准的,明显的或通用的方法来解决这个问题?

脱离我的头顶:

  • 将'current_transaction_guid'属性添加到所有域
  • 每个域都有一个审核/历史记录域,用于存储以前的版本(带有ID)
  • 当交易开始时,使用唯一ID(例如GUID)写入“交易”域,开始日期/时间,is_complete = false
  • 将更改写入对象时,请将现有版本存储在历史记录表
  • 在所有域中写入更改,在每种情况下更新current_transaction_guid属性
  • (完成写入/更新后)将事务对象is_complete更新为true
  • 将所有域对象current_transaction_guid更新为null
  • 在读/写/将任何内容带入事务之前,请检查current_transaction_guid。如果为null,则继续,但如果不为null,则读取事务状态。如果is_complete = false,请等待'true'或直到事务超时;如果is_complete = true,请等待一小段时间,然后将current_transaction_guid更新为null
嗯,来想一想,也许这不值得麻烦,最好将所有涉及的域的数据汇集到一个域中,即使大量冗余也是如此?一致的读取和乐观并发(通过版本号)应该足够了吗?

1 个答案:

答案 0 :(得分:2)

我设计了一个与SimpleDB一起使用的事务系统。由于最终的一致性,我不确定您的上述方案是否有效。虽然可以使用一致的读取,但这会影响您的性能并抵消使用SimpleDB的可扩展性优势( - 可能更好地使用RDBMS服务器集群)。

我的机制不使用一致性读取,并利用SimpleDB的多值项目功能来存储事务,值对的历史记录。交易ID和状态存储在交易域中,该域还记录交易影响的域/列。

在读取时,可以通过构造树来确定col的一致值,其中节点是值(当前和历史)并且连接是版本 - > prev_version依赖性并且在拓扑上对其进行排序。如果有一个尾部(拓扑排序中唯一的最后一个元素),那么这就是该列的一致值。属于未提交值的值将在该进程中被忽略。 如果没有唯一的尾部,则表示存在冲突。在分布式系统中无法避免冲突 - 由于物理原因 - 不可能有一个中央时钟来对应时间戳(或版本计数)值。这将需要组成系统的所有服务器之间的0ms延迟连接(这是不可能的 - 请问爱因斯坦)。在发现冲突的地方,我们将其传递给应用程序进行解决( - 因为它有时并不重要,通常可以通过模型中的其他信息解决)。

我们还为事务开始加时间戳,如果超时已经过去,则假定中止未标记为已提交或已中止的表中的任何事务。 事务和历史值可以在任何点处从行中删除,在这些行中,它们是所有拓扑排序中的唯一节点。

如果您决定朝这个方向前进,希望能给您(或某人)一些想法。