Transactions 两阶段提交协议的ACID是多少?

Transactions 两阶段提交协议的ACID是多少?,transactions,distributed-transactions,Transactions,Distributed Transactions,我遇到了一种情况,我开始怀疑两阶段提交协议是否真的保证了ACID属性,特别是其中的“a”部分 让我们来看一个涉及2个资源的理论分布式事务。(关于我必须处理的问题的更实际的描述,你可以在中找到)。该场景是分布式事务的正常执行(无故障或恢复)。应用程序启动事务、更新资源并发出commit()调用。提交完成后,应用程序将检查两个资源,并查看已完成事务中的所有更改。一切都很好,2PC协议完成了它的工作,对吗 现在,对场景进行一个小的更改。当分布式事务执行commit()时,另一个应用程序将访问相同的2个

我遇到了一种情况,我开始怀疑两阶段提交协议是否真的保证了ACID属性,特别是其中的“a”部分

让我们来看一个涉及2个资源的理论分布式事务。(关于我必须处理的问题的更实际的描述,你可以在中找到)。该场景是分布式事务的正常执行(无故障或恢复)。应用程序启动事务、更新资源并发出commit()调用。提交完成后,应用程序将检查两个资源,并查看已完成事务中的所有更改。一切都很好,2PC协议完成了它的工作,对吗

现在,对场景进行一个小的更改。当分布式事务执行commit()时,另一个应用程序将访问相同的2个资源。它能否只看到事务中的部分更改?比方说,对一个资源的更改已经可见,而对第二个资源的更改还不可见


在我读到的关于2PC协议的所有信息中,我找不到任何关于单个资源相对于彼此的变化可见性的保证。我找不到任何东西表明所有资源在完全相同的时间完成各自的提交。

我想你把2PC和。两阶段提交确保事务中的所有参与线程要么提交,要么中止。并发控制确保在相同或不同的应用程序中对事务进行某种排序。根据您的需求,有各种不同的处理方法,但完全序列化事务当然是可能的。

我认为您混淆了主题。2PC确保事务以一定的可见性提交。也就是说,在您的事务中,您提交的数据将以特定的方式排序,并且使用该事务提交的数据将以串行方式提交

在事务之外,您看到的行为将取决于锁定在数据库中的工作方式。通常,您会期望只读查询会看到事务之前的状态或事务之后的状态(除非使用相同的锁定语义,否则无法保证它接收到的是哪种状态)。写语义通常会导致锁定事务中的所有项,但这实际上取决于数据库的配置方式

2PC实际上只承诺一个操作是原子的,即使这样,它也只在该事务的范围内是原子的,这取决于数据库的配置方式。

来自Wikipedia 在早期明确指出2PC并非对所有可能的故障配置都具有弹性。此处有更具体的参考:

3PC最初由Dale Skeen和Michael Stonebraker在他们的论文《分布式系统中碰撞恢复的正式模型》中描述[1]在这项工作中,他们将2PC建模为一个非确定性有限状态自动机系统,并证明它对随机单点故障没有弹性

编辑:这可用于中断所有4种酸属性。我最初的回答是错误的

变化的可见性 是一个正交问题,取决于所涉及的队列配置(请参阅)

你的问题的主体和主题是关于孤立性,而不是原子性。原子性意味着事务始终结束,最终提交所有更改(或回滚所有更改)

即使所有队列都是可序列化的,并且使用相同的TransactionManager,我仍然可以通过在正确的时间启动新事务来避免隔离

在研究了你的博客之后,我会说,两阶段提交协议不能解决你的问题,MDB通信必须更具创造性地重新设计

根据个人经验
由于阻塞的性质,2PC在几乎任何实际情况下都是一种过度使用,明智地设计存储位置和数据流可以提供更好的解决方案。基本上,您需要任何类型的信息的唯一最权威的来源,并且所有其他相关方必须能够将自己更新到该权威状态。是一个伟大的灵感,尤其是在中实现的。现代分布式数据库是BASE而不是ACID()。

我不会将2PC与并发控制混淆。当我依赖于事务基础设施来正确地完成它时,我没有考虑它。事实是:一,。如果我使用的是非分布式事务,我不必担心这一点。(如果这样的事务更改了数据库中的多个表,则与提交的第一个事务并行运行的其他应用程序不会看到一个表的更改,但不会看到其他表的更改。)。我甚至可能不知道我正在分布式事务中运行。即使我知道:已经有一个重型的基础设施来确保一些基本的事务属性。为什么我需要在它旁边发明我自己的来确保它?4.在阅读了[2PC][1]和有关原子提交的链接文章后,我的理解是:我可以放心地从2PC中获得“全部或全部”语义。[1] :您说“如果这种[非分布式]事务更改了数据库中的多个表,则在提交第一个事务的同时运行的其他应用程序不会看到一个表的更改,但不会看到其他表的更改”,但这不是真的。如果您有一个可重复读取隔离级别,事务a从表X读取,然后事务B写入表X和Y,然后事务a从X重新读取,也从Y读取,它将从X看到旧数据,从Y看到新数据。假设这种情况:1。首先我们有a=0,b=0;2.事务需要设置a=1和b=2;3.2件装,a和