Skip to content

Instantly share code, notes, and snippets.

@ideawu
Last active March 19, 2021 08:02
Show Gist options
  • Save ideawu/8e4bfe358e9a71533e202ae76e115598 to your computer and use it in GitHub Desktop.
Save ideawu/8e4bfe358e9a71533e202ae76e115598 to your computer and use it in GitHub Desktop.
数据库事务原子性

事务原子性

例如在事务中往一个空集合中 prepare 添加一个元素, 之后, 事务中心已经提交, 但元素仍是 prepared 状态. 如果此时去读这个元素, 可以读到, 向事务中心求证, 发现其是 committed 状态. 但如果去读集合计数, 仍然是 0, 因为元素只在变更为 committed 状态时才更新集合计数.

一个事务, set a=1, set b=2. 如果先读发现 a=1, 然后去读发现 b=0, 这种行为是否违反事务 ACID 的原子性?

如果先读发现 b=0, 再读发现 a=1, 我认为符合原子性. 但反过来我认为不符合, 因为发现 a=1 时, 可以推导出事务已经提交, 既然已经提交, 那么 b=2 也应该已经提交.

为了达到原子性, 应该加上读修复功能. 当读发现 prepare 状态的资源时, 应该尝试修复: 如果确认是 prepared 状态, 立即返回旧值. 如果确认是 committed 状态, 修复(或者等待, 不主动修复), 然后再返回新值.

对于 2PC 实现, 强原子性几乎不可能实现. 例如容器中的某一个元素是 prepared 状态, 但其对应的事务对象(commit point)已经 committed, 所以本质上元素应该也是 committed. 但不可能做到 commit point 和 cohort "同时"更新状态. 当我们去读容器的 size 时, 我们无法知道它是否包含有 prepared 状态的元素, 所以, 容器的 size 一定是"错误的". 既然对于容器, 无法实现强原子性, 我们索性只承诺最终原子性, 读操作总是忽略 prepared 状态的数据即可, 也即前面说的, 先读到 a=1, 然后又读到 b=0.

如果非要往隔离级别上靠, 那便是 Eventual Read Committed, 保证最终结果, 不保证立即结果. 事务的执行者在全部 cohort 都 commit 之后再返回, 这样可以实现先后顺序的原子性, 但在 commit 之前读的话, 无法保证, 可能只读到部分 committed 的结果.

不实现交互式事务. 事务只有写操作, 读操作独立于事务之外.

@ideawu
Copy link
Author

ideawu commented Mar 15, 2021

https://www.cockroachlabs.com/blog/how-cockroachdb-distributes-atomic-transactions/ 提到"Filter: Reading an Intent", 也即读到 prepared 状态的数据应该如何处理. 它这种逻辑并不能正确处理级联关系, 也即读取容器的属性时, 并不知道容器内的元素是否为 prepared 状态, 但容器内的元素明显会影响(级联)容器的属性.

@ideawu
Copy link
Author

ideawu commented Mar 15, 2021

如果只实现最终原子性的话, 那么 prepare 阶段只需要给资源加锁, prepared 的数据依然保存到协调者那里. 这样, 资源的 prepare 操作会变得很简单, 只需要让资源关联到 xid(事务ID) 即可.

@ideawu
Copy link
Author

ideawu commented Mar 19, 2021

Google Cloud Datastore 在点查时, 可以实现强原子性, 但在扫描时(索引查询)不承诺强原子性. https://cloud.google.com/datastore/docs/articles/balancing-strong-and-eventual-consistency-with-google-cloud-datastore?hl=zh-cn#eventual-consistency-on-reading-an-index

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment