单领导者(交易)相对于多领导者复制的优势

Ste*_*hen 5 replication transaction

我正在阅读我衷心推荐的优秀书籍“设计数据密集型应用程序”,但我对比较多领导者(即多写入者)复制与单领导者复制的部分感到困惑。我理解基本的区别:在多领导者中,多个领导者节点可以接受写入,每个领导者将其写入发送给其他领导者,并且您有冲突解决规则来决定如何合并它们。单一领导者使用事务来解决并发。

\n\n

以下两段描述了多作者如何变得更具挑战性,因为冲突无法立即解决。我的问题是后来的。

\n\n
\n

[本段和图表描述了多领导者。] 例如,考虑一个由两个用户同时编辑的 wiki 页面,如图 5-7 [复制如下] 所示。用户 1 将页面标题从 A 更改为 B,同时用户 2 将页面标题从 A 更改为 C。每个用户\xe2\x80\x99 的更改都会成功应用于其本地领导者。但是,当异步复制更改时,会检测到冲突。在单领导者数据库中不会出现此问题。

\n\n

在单主数据库中,第二个写入器将阻塞并等待第一个写入完成,或者中止第二个写入事务,迫使用户重试写入。另一方面,在多领导者设置中,两次写入都会成功,并且仅在稍后的某个时间点异步检测到冲突。到那时,要求用户解决冲突可能为时已晚。

\n
\n\n

在此输入图像描述

\n\n

我在这里看到了多作者的困难,但我怀疑单作者会好得多。

\n\n

考虑当两个人大致同时编辑维基百科页面时最可能发生的事件链:1) 第 1 个人加载编辑页面,花费 3-5 秒编辑标题并提交。2) 第二个人加载编辑页面,花费3-5秒编辑标题并提交。应用编辑的每个数据库事务只有几毫秒,因此更新更有可能相继发生,而不是同时发生。因此,如果您担心这两个人之一的更新将会丢失,您需要以某种方式解决应用程序级别的潜在冲突;交易不会真正帮助你。

\n\n

此外,在两个事务确实重叠的情况下,用户简单地延迟其中一个事务直到另一个事务完成并没有帮助。一旦恢复,它仍然会覆盖第一个用户的数据。

\n\n

所以我的问题是,是否有一些我缺少的有用的交易技术在这里实际上有用?我已经有一段时间没有尝试使用事务了,所以我的技术已经生锈了。

\n\n

我能想到的最好的改进是:添加AND title=\'A\'到两个语句的末尾UPDATE,并向事务中添加第二个语句来检查受影响的行数,如果等于 0 则回滚。回滚不会产生任何效果,但会向客户端指示失败。但这有点hackish。

\n\n

我认为用支票开始交易没有什么帮助(即SELECT * FROM pages WHERE title=\'A\'确保你能收回一些东西)。即使只有一个交易胜出,两个交易也可能在开始时看到“A”。

\n

Mic*_*utz 0

验证数据没有改变

无状态应用程序也有类似的问题。(例如网络)

数据可以在“选择要显示的数据进行编辑”和“最终用户单击按钮UPDATE”之间进行更改。

SELECT为了确保数据在和请求之间没有更改UPDATE,该UPDATE过程应该:

  1. 使用某种锁序列化对行的访问。
    • Oracle 开发人员更喜欢SELECT ... FOR UPDATE
  2. 验证数据没有改变。
    • 计算哈希值并比较之前/之后的值。
    • 或者查看“上次更新时间戳”列并比较之前/之后的值。
  3. 相应地执行 DML。
  4. COMMIT/ ROLLBACK& 释放锁。
    • COMMITOracle行锁通过/释放ROLLBACK
  5. 必要时提出错误。

这个的实现是非常公式化的。

该逻辑可以在用于创建应用程序的框架内实现(例如,进程Oracle APEX“自动DML”默认执行此操作)。

基于模板的代码生成器可以生成通过使用适当的模板实现此逻辑的过程/函数(表 API [TAPI])。