【发布时间】:2020-03-22 06:24:35
【问题描述】:
假设在“db1”中有一个名为“t1”的表,在“db2”中有一个名为“t2”的表,我需要在两个表上插入一条记录,否则失败。
连接到 db1 我想我应该输入这个
BEGIN;
PREPARE TRANSACTION 'pepe'; -- this says the manual that makes your transaction gets stored on disk, so what is the purpose if i can't use it from another database?)
insert into t1 (field) values ('a_value');
COMMIT PREPARED 'pepe'
我猜是连接到 db2
BEGIN;
PREPARE TRANSACTION 'pepe'; -- this fails (the name of the transacttion, what is the meaning, what is use for?)
-- It complains about this "ERROR: transaction identifier "pepe" is already in use"
insert into t2 (field) values ('another_value');
COMMIT PREPARED 'pepe'
正如您所见,我不知道如何在 postgres 上使用两阶段提交。
TL;DR
我不知道如何在同一个 RDBMS 中的不同数据库上执行同步命令。
我已阅读 at oficial postgres documentation,为了在两个或多个不相关的 postgres 数据库中同步工作,我们可以使用所谓的“两阶段提交”协议的实现。
所以我开始尝试看看人们是如何在 postgres 中实际使用它们的,我没有看到任何实际的例子,最多我得到一个人的this post,他试图尝试连接到几个 postgres 客户端不同的数据库,以模拟并行运行的多个进程对多个数据库的处理,这些数据库应该以感激(全部提交)或可怕的方式(全部回滚)结束。
我看到的其他来源是:
-
https://en.wikipedia.org/wiki/Two-phase_commit_protocol(此来源
很好地解释协议,但真的让我想知道在哪里或是谁
我的“协调员”以及如何向“参与者”发送消息……我
只有
prepare transaction <id>、commit prepared <id>或rollback prepared <id>任我支配的命令) - Two phase commit
- https://dba.stackexchange.com/questions/145656/dependent-transaction-in-separate-database-connections
- https://www.endpointdev.com/blog/2010/07/distributed-transactions-and-two-phase/
- https://www.citusdata.com/blog/2017/11/22/how-citus-executes-distributed-transactions/
- (来自 golang 客户端应用程序)https://github.com/go-pg/pg/issues/490
我真的很困惑,我希望 horse_with_no_name 出现在这里并启发我(就像过去发生的那样)或任何其他可以帮助我的慈善灵魂。
提前致谢!
分辨率(在 Laurenz 的回答之后)
连接到 db1,这些是要执行的 sql 行:
BEGIN;
-- DO THINGS TO BE DONE IN A ALL OR NOTHING FASHION
-- Stop point --
PREPARE TRANSACTION 't1';
COMMIT PREPARED 't1' || ROLLBACK PREPARED 't1' (decision requires awareness and coordination)
同时连接到 db2 这些将是要执行的脚本:
BEGIN;
-- DO THINGS TO BE DONE IN A ALL OR NOTHING FASHION
-- Stop point --
PREPARE TRANSACTION 't2';
COMMIT PREPARED 't2' || ROLLBACK PREPARED 't2'
-
-- Stop point --是协调进程(例如 执行语句的应用程序,或 psql 背后的人 客户端控制台或 pgAdminII) 应停止两者的执行 脚本(实际上不执行任何进一步的指令,这就是我所说的停止)。 -
然后,首先在 db1 上(然后在 db2 上,反之亦然) 协调进程(无论是否为人)必须在每个连接上运行
PREPARE TRANSACTION。- 如果其中一个失败,则协调器必须在已经准备好事务的那些数据库上运行
ROLLBACK PREPARED,在其他数据库上运行ROLLBACK。 - 如果没有人失败,则协调员必须在所有相关数据库上运行 COMMIT PREPARED,这是一项永远不会失败的操作(例如,当您离家一步,所有东西都已正确设置为安全退出时,就已经有了家)李>
- 如果其中一个失败,则协调器必须在已经准备好事务的那些数据库上运行
【问题讨论】:
-
猜这对我有帮助...stackoverflow.com/questions/8953423/…,我花了很多时间查看两阶段提交而不是准备事务...:S
-
上面的链接有一个奇怪的例子,我猜,根据 Laurenz 的回答,它没有准备两个交易,它使用两个数据库...
-
请注意,您提到的一篇文章已移至此处:endpointdev.com/blog/2010/07/…
标签: postgresql two-phase-commit