注: 本文为云贝教育 刘峰 原创,请尊重知识产权,转发请注明出处,不接受任何抄袭、演绎和未经注明出处的转载。
两阶段提交(Two-Phase Commit,2PC)是一种在分布式系统中确保事务原子性的协议。在PostgreSQL中,两阶段提交允许你创建一个预备事务,这个预备事务可以在一个或多个数据库之间进行提交或回滚,从而确保所有的数据库要么都提交事务,要么都不提交。
两阶段提交在PostgreSQL中的使用通常涉及以下步骤:
1. 准备事务:在PostgreSQL中,你可以通过`PREPARE TRANSACTION 'transaction_id';`命令来准备一个事务。这个命令会开始一个事务,但不会立即提交它。在这个阶段,所有的事务更改都会被保存,但还没有被最终提交。
2. 提交或回滚事务:一旦事务被准备好,你可以选择提交或回滚事务。如果你想提交事务,可以使用`COMMIT PREPARED 'transaction_id';`命令。如果你想回滚事务,可以使用`ROLLBACK PREPARED 'transaction_id';`命令。在这个阶段,所有的数据库都会同步执行相同的操作,从而确保事务的一致性。
请注意,两阶段提交协议是一种强一致性协议,它可能会影响系统的性能。在选择使用它时,需要权衡一致性和性能之间的关系。
该参数必须重启才能生效,设置为10
- postgre=# select name,setting from pg_settings where name like '%transactions%';
- name | setting
- ---------------------------+---------
- max_prepared_transactions | 10
- (1 row)
- postgre=# create table testtab0l(id int primary key);
- CREATE TABLE
- postgre=# begin;
- BEGIN
- postgre=# insert into testtab0l values(1);
- INSERT 0 1
- postgre=# PREPARE TRANSACTION 'pg global trans 0001';
- PREPARE TRANSACTION
命令中“osdba global trans0001”是两阶段提交中全局事务的ID,由事务协调器生成(事务协调器也可能是由应用实现的,事务协调器会持久化这个全局事务ID.PostgreSQL数据库一旦 成功执行这条命令,就会把此事务持久化,意思是即使数据库重启,此事务既不会回滚,也不会丢失)。
$ pg_ctl restart -d $PGDATA
- [postgre@cdh02 ~]$ psql
- psql (12.4)
- Type "help" for help.
-
- postgre=# select * from testtab0l;
- id
- ----
- (0 rows)
- ---此时无数据
2.5 提交全局事务
- postgre=# COMMIT PREPARED 'pg global trans 0001';
- COMMIT PREPARED
- postgre=# select * from testtab0l;
- id
- ----
- 1
- (1 row)
从上面的例子可以看出,一旦成功执行“PREPARE TRANSACTION”命令,事务就会被持久化,即使重启数据库,仍然可以提交这个事务,事务中的操作不会丢失。