Vic*_*tor 7 postgresql two-phase-commit
假设“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'
Run Code Online (Sandbox Code Playgroud)
连接到db2,我猜:
BEGIN;
PREPARE TRANSACTION 'pepe'; -- this fails (the name of the transaction, 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'
Run Code Online (Sandbox Code Playgroud)
正如您可能看到的,我不明白如何在 Postgres 上使用两阶段提交。
我不知道如何在同一 RDBMS 中的不同数据库上执行同步命令。
我在 Postgres 文档中读到,为了在两个或多个不相关的 Postgres 数据库之间同步工作,我们可以使用所谓的“两阶段提交”协议的实现。
所以我开始尝试看看人们如何在 Postgres 中实际使用它们,我没有看到任何实际的例子,最多我看到了一个人的这篇文章,他试图按顺序连接到不同数据库的几个 Postgres 客户端进行实验模拟并行运行的多个进程对多个数据库执行操作,这些数据库应以成功(所有提交)或失败结果(所有回滚)结束。
我见过的其他例子有:
prepare transaction <id>,commit prepared <id>或
rollback prepared <id>我可以使用的命令)连接到 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)
Run Code Online (Sandbox Code Playgroud)
同时连接到 db2 将执行以下脚本:
BEGIN;
-- DO THINGS TO BE DONE IN A ALL OR NOTHING FASHION
-- Stop point --
PREPARE TRANSACTION 't2';
COMMIT PREPARED 't2' || ROLLBACK PREPARED 't2'
Run Code Online (Sandbox Code Playgroud)
协调器进程-- Stop point --(例如执行该语句的应用程序,或者 psql 客户端控制台或 pgAdminII 后面的人员)应停止执行两个脚本(实际上不执行任何进一步的指令,这就是我所说的停止)。
然后,首先在 db1 上(然后在 db2 上,反之亦然)协调器进程(无论是否为人为进程)必须PREPARE TRANSACTION在每个连接上运行。
ROLLBACK PREPARED 在事务已准备好的数据库和 ROLLBACK 其他数据库上运行。Lau*_*lbe 15
我想你误会了PREPARE TRANSACTION。
该语句结束事务的工作,也就是说,应该在所有工作完成后发出该语句。这个想法是,PREPARE TRANSACTION除了提交本身之外,执行提交期间可能失败的所有操作。那就是保证后续COMMIT PREPARED不会失败。
其思路是处理如下:
START TRANSACTION在分布式事务涉及的所有数据库上运行。
做好所有的工作。如果有错误,ROLLBACK则所有交易。
PREPARE TRANSACTION在所有数据库上运行。如果在任何地方失败,请ROLLBACK PREPARED在已准备好事务的数据库和ROLLBACK其他数据库上运行。
一旦PREPARE TRANSACTION在所有地方都成功,就可以COMMIT PREPARED在所有涉及的数据库上运行。
这样,您就可以保证多个数据库之间的“全有或全无”。
这里我没有提到的一个重要组件是分布式事务管理器。它是一个软件,可以永久记住上述算法当前处理的位置,以便在崩溃后可以进行清理或继续提交。
如果没有分布式事务管理器,两阶段提交没有多大价值,而且实际上很危险:如果事务陷入“准备”阶段但尚未提交,它们将继续持有锁并且(在以下情况下) PostgreSQL)即使在服务器重新启动时也会阻止自动清理工作,因为此类事务必须是持久的。
这很难做到正确。
| 归档时间: |
|
| 查看次数: |
8348 次 |
| 最近记录: |