本次小崔简单介绍一个有关pg transaction 二阶段提交的特点
postgresql支持两阶段提交,并且两阶段提交是实现分布式事务的关键。
两阶段提交有以下4个阶段:
应用程序先操作该数据库,但是不提交transaction。此时调用事务协调器的一些提交方法,注意该事务协调器有可能是客户自己程序开发。
事务协调器去联络数据库,通知数据库即将进行提交。在postgresql的client当中使用prepare transaction 'TRANSACTION_ID' , 该TRANSACTION_ID 为自我定义的全局transaction_id
收到了prepare transaction后,数据库一定要处于一个可以commit 或者可以rollback的状态。数据库不能挂起或者其他不可执行事务操作的状态。如果该过程success,则将‘标记’的transaction操作持久化。
第二阶段,此时数据库需要为事务协调器去发起一个指令,通知事务协调器是要将事务提交还是回滚,即commit prepared 'TRANSACION_ID' rollback prepared 'TRANSACTION_ID' 。如果是多个数据库做分布式的话,需要多个数据库共同返回一个success,如果有一个数据库没有返回success的话,则所有的数据库都不会提交。
先看下实验:
要是使用二阶段提交,需要将参数max_prepared_transactions设置成>0的数
修改参数文件postgresql.conf
创建一张表:
create table test1 (id int primary key) ;
开启session:
postgres=# begin;
BEGIN
postgres=# insert into test values (1);
INSERT 0 1
postgres=# prepare transaction 'trans_test_001';
PREPARE TRANSACTION
这里得trans_test_001是一个全局的事务编号
查看视图有记录
postgres=# select * from pg_prepared_xacts
;
transaction | gid | prepared | owner | database
-------------+----------------+-------------------------------+----------+----------
1901 | trans_test_001 | 2019-12-01 05:04:11.148557-05 | postgres | postgres
此时,会有事务协调器将该session做过的操作持久化,也就是说即使该session断开或者是数据库重启都不会失去这条记录。
session 退出:
postgres=# select * from pg_prepared_xacts ;
transaction | gid | prepared | owner | database
-------------+----------------+-------------------------------+----------+----------
1901 | trans_test_001 | 2019-12-01 05:04:11.148557-05 | postgres | postgres
(1 row)
postgres=# \q
-bash-4.2$ psql
psql (9.2.24)
Type "help" for help.
postgres=# select * from pg_prepared_xacts ;
transaction | gid | prepared | owner | database
-------------+----------------+-------------------------------+----------+----------
1901 | trans_test_001 | 2019-12-01 05:04:11.148557-05 | postgres | postgres
(1 row)
db重启:
-bash-4.2$ pg_ctl -D postgres/ restart
waiting for server to shut down....... done
server stopped
server starting
-bash-4.2$ psql
psql (9.2.24)
Type "help" for help.
postgres=# select * from pg_prepared_xacts ;
transaction | gid | prepared | owner | database
-------------+----------------+-------------------------------+----------+----------
1901 | trans_test_001 | 2019-12-01 05:04:11.148557-05 | postgres | postgres
(1 row)
再次commit或者rollback
commit prepared 'trans_test_001';
rollback prepared 'trans_test_001';
postgres=# commit prepared 'trans_test_001';
COMMIT PREPARED
postgres=#
postgres=#
postgres=# select * from test1;
id
----
3
(1 row)
THAT'S ALL
BY CUI
本文分享自微信公众号 - 最帅dba工作笔记,如有侵权,请联系 service001@enmotech.com 删除。